o
    ưiU                     @   s`  U d Z ddlZddlmZmZmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZ ddl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 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- ddl.m/Z/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z; e"j<e"j=e"j>e"j>dZ?ee@e"f eAd< G dd deZBdS )zJ
This file contains the transformation logic for the Gemini realtime API.
    N)AnyDictListOptionalUnioncast)verbose_logger)uuid)Logging)BaseRealtimeConfigVertexGeminiConfig) LiteLLMCompletionResponsesConfig)AutomaticActivityDetection BidiGenerateContentRealtimeInput&BidiGenerateContentRealtimeInputConfig BidiGenerateContentServerContent BidiGenerateContentServerMessageBidiGenerateContentSetup)OpenAIRealtimeContentPartDone%OpenAIRealtimeConversationItemCreatedOpenAIRealtimeDoneEventOpenAIRealtimeEventsOpenAIRealtimeEventTypesOpenAIRealtimeOutputItemDoneOpenAIRealtimeResponseAudioDone&OpenAIRealtimeResponseContentPartAddedOpenAIRealtimeResponseDelta OpenAIRealtimeResponseDoneObjectOpenAIRealtimeResponseTextDone&OpenAIRealtimeStreamResponseBaseObject+OpenAIRealtimeStreamResponseOutputItemAddedOpenAIRealtimeStreamSession!OpenAIRealtimeStreamSessionEventsOpenAIRealtimeTurnDetection)GeminiResponseModalitiesHttpxBlobTypeHttpxContentType)ALL_DELTA_TYPES'RealtimeModalityResponseTransformOutputRealtimeResponseTransformInputRealtimeResponseTypedDict)get_empty_usage   )encode_unserializable_typesget_api_key_from_env)ZsetupCompletez serverContent.generationCompletezserverContent.turnCompletezserverContent.interrupted MAP_GEMINI_FIELD_TO_OPENAI_EVENTc                   @   s"  e Zd Z	dVdededee defddZ	dVdee dedee defd	d
Zdede	fddZ
dee de	fddZdWdefddZdedefddZdedee fddZdededefddZ	dVdededee dee fd d!Z	dVded"edee defd#d$Z	dVd%eee  defd&d'Z	dVd(ed)ed*ededee dee fd+d,Zded)ed(ededef
d-d.Zd/eee  d0ee d1ee dedeee f f
d2d3Z!d0ee d1ee d4eee f dedee f
d5d6Z"e#d7ed8ede$fd9d:Z%d;eeee f d<eee  deee  fd=d>Z&d;eeee f d?eee'  deee'  fd@dAZ(	dVde)d1ee dBee dCeee'  dee de*fdDdEZ+dFe	dGedHe,dede-f
dIdJZ.dKededLee dGede	f
dMdNZ/deee0f dedOe1dHe,de2f
dPdQZ3defdRdSZ4dedefdTdUZ5dS )XGeminiRealtimeConfigNheadersmodelapi_keyreturnc                 C   s   |S N )selfr2   r3   r4   r7   r7   b/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/gemini/realtime/transformation.pyvalidate_environmentD   s   z)GeminiRealtimeConfig.validate_environmentapi_basec                 C   sP   |du rd}|du rt  }|du rtd|dd}|dd}| d| S )	z
        Example output:
        "BACKEND_WS_URL = "wss://generativelanguage.googleapis.com/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent"";
        Nz'wss://generativelanguage.googleapis.comz(api_key is required for Gemini API callszhttps://zwss://zhttp://zws://zR/ws/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent?key=)r/   
ValueErrorreplace)r8   r;   r3   r4   r7   r7   r9   get_complete_urlI   s   z%GeminiRealtimeConfig.get_complete_url
model_turnc                 C   sr   d|v r2|d }t |dkrtdt | d |d }d|v r$tjS d|v r+tjS td| td	| )
aO  
        Map the model turn event to the OpenAI realtime events.

        Returns either:
        - response.text.delta - model_turn: {"parts": [{"text": "..."}]}
        - response.audio.delta - model_turn: {"parts": [{"inlineData": {"mimeType": "audio/pcm", "data": "..."}}]}

        Assumes parts is a single element list.
        parts   zRealtime: Expected 1 part, got z for Gemini model turn event.r   text
inlineDatazUnexpected part type: z-Unexpected model turn event, no 'parts' key: )lenr   warningr   RESPONSE_TEXT_DELTARESPONSE_AUDIO_DELTAr<   )r8   r?   r@   partr7   r7   r9   map_model_turn_eventZ   s   z)GeminiRealtimeConfig.map_model_turn_event
delta_typec                 C   s*   |dkrt jS |dkrt jS td| )NrB   audiozUnexpected delta type: )r   RESPONSE_TEXT_DONERESPONSE_AUDIO_DONEr<   )r8   rJ   r7   r7   r9   map_generation_complete_eventu   s
   z2GeminiRealtimeConfig.map_generation_complete_eventpcm16input_audio_formatc                 C   s   dddd}| |dS )Nz	audio/pcmz
audio/pcmuz
audio/pcma)rO   Z	g711_ulawZ	g711_alawzapplication/octet-stream)get)r8   rP   Z
mime_typesr7   r7   r9   get_audio_mime_type   s
   z(GeminiRealtimeConfig.get_audio_mime_typevaluec                 C   s|   t  }d|v rt|d tr|d  |d< nd|d< d|v r+t|d tr+|d |d< d|v r<t|d tr<|d |d< |S )NZcreate_responsedisabledTZprefix_padding_msZprefixPaddingMsZsilence_duration_msZsilenceDurationMs)r   
isinstanceboolint)r8   rS   Zautomatic_activity_dectionr7   r7   r9   map_automatic_turn_detection   s   
z1GeminiRealtimeConfig.map_automatic_turn_detectionc                 C   s   g dS )N)instructionstemperaturemax_response_output_tokens
modalitiestoolsinput_audio_transcriptionturn_detectionr7   )r8   r3   r7   r7   r9   get_supported_openai_params   s   z0GeminiRealtimeConfig.get_supported_openai_paramsoptional_paramsnon_default_paramsc           	      C   s8  d|vri |d< |  D ]\}}|dkr tdd|igd|d< q|dkr+||d d< q|dkr6||d d	< q|d
krKdd ttt |D |d d< q|dkrdddlm} | }|j||d|d d< q|dkrq|d urqi |d< q|dkrtt|}| 	|}t
|dkrt|d|d< qt
|d dkr|d |S )NgenerationConfigrY   userrB   )roler@   systemInstructionrZ   r[   maxOutputTokensr\   c                 S      g | ]}|  qS r7   )upper.0Zmodalityr7   r7   r9   
<listcomp>       z:GeminiRealtimeConfig.map_openai_params.<locals>.<listcomp>responseModalitiesr]   r   r   )rS   ra   r^   inputAudioTranscriptionr_   )ZautomaticActivityDetectionZrealtimeInputConfig)itemsr'   r   r   str@litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_geminir   Z_map_functionr$   rX   rD   r   pop)	r8   ra   rb   keyrS   r   Zvertex_gemini_configZvalue_typedZ!transformed_audio_activity_configr7   r7   r9   map_openai_params   sL   



z&GeminiRealtimeConfig.map_openai_paramsmessagesession_configuration_requestc                 C   s  i }zt |}W n  t jy)   t|tr|jddd}nt|}td| w g }|d}|dkrQ| j	i |d d}	d	| |	d
< |
t d|	i |S |dkrWg S |dkrht|  |d d|d< n*|dkr|di }
|
dg }dd |D }dtd |}|sg S ||d< ng S t|dkrtdt| dt|  tttttttf |}|
t d|i |S )Nutf-8r=   errorsInvalid JSON message: typezsession.updatesession)ra   rb   models/r3   setupzresponse.createzinput_audio_buffer.appendrK   )ZmimeTypedatazconversation.item.createitemcontentc                 S   s0   g | ]}t |tr|d dkr|ddqS )r|   Z
input_textrB    )rU   dictrQ   )rk   cr7   r7   r9   rl      s    
zCGeminiRealtimeConfig.transform_realtime_request.<locals>.<listcomp> rB   rA   z"Only one argument can be set, got z: Zrealtime_input)jsonloadsJSONDecodeErrorrU   bytesdecoderq   r<   rQ   ru   appenddumpsr&   rR   joinfilterrD   listkeysr   r   r.   r   object)r8   rv   r3   rw   Zrealtime_input_dictjson_messagemessage_strmessagesmsg_typeZ$client_session_configuration_requestr   Zcontent_listZ
text_partsrB   r7   r7   r9   transform_realtime_request   sb   



z/GeminiRealtimeConfig.transform_realtime_requestlogging_session_idc                 C   s   |rt |di }ni }|dp|}|di pi }|ddg}dd ttt |D }|d}	t||d	}
|	d urHt|	trH|	|
d
< |d urst|trsd|v r_|dd |
d< n|	dro|t
dd  |
d< n||
d< td|
tt dS )Nr   r3   rc   rn   TEXTc                 S   rh   r7   lowerrj   r7   r7   r9   rl   .  rm   zHGeminiRealtimeConfig.transform_session_created_event.<locals>.<listcomp>rf   )idr\   rY   z/models/r~   zsession.created)r|   r}   event_id)r   r   rQ   r   r   rq   r"   rU   split
startswithrD   r#   r	   uuid4)r8   r3   r   rw   "session_configuration_request_dict_modelgeneration_configgemini_modalities_modalitiesZ_system_instructionr}   r7   r7   r9   transform_session_created_event  sD   

z4GeminiRealtimeConfig.transform_session_created_eventprevious_messagesc                 C   s>   |d u s
t |dkrdS d|d v r|d d drdS dS )Nr   Tr|   r   deltaF)rD   endswith)r8   r   r7   r7   r9   _is_new_content_deltaM  s   z*GeminiRealtimeConfig._is_new_content_deltaresponse_idoutput_item_idconversation_idc                 C   s>  |d u rt dt|di }|di }|ddg}dd ttt |D }	|d}
|d	}g }td
dt	
 d|dg ||	|
|dd}|| td|d|ddddg dd}|| tddt	
 |ddddg dd}|| tddddt	
 ||dkrdddnddd|d}|| |S ) Nz>session_configuration_request is required for Gemini API callsr   rc   rn   r   c                 S   rh   r7   r   rj   r7   r7   r9   rl   m  rm   zHGeminiRealtimeConfig.return_new_content_delta_events.<locals>.<listcomp>rZ   rg   zresponse.createdevent_{}realtime.responseZin_progress)r   r   statusoutputr   r\   rZ   max_output_tokensr|   r   responsezresponse.output_item.addedr   realtime.itemrv   	assistantr   r   r|   r   re   r   )r|   r   output_indexr   zconversation.item.created)r|   r   r   zresponse.content_part.addedrB   r   r|   rB   rK   r|   
transcript)r|   content_indexr   r   item_idrH   r   )r<   r   r   rQ   r   r   rq   r    formatr	   r   r   r!   r   r   )r8   r   r   r   rJ   rw   r   r   r   r   Z_temperatureZ_max_output_tokensZresponse_itemsZresponse_createdZresponse_output_item_addedZconversation_item_createdZresponse_content_part_addedr7   r7   r9   return_new_content_delta_eventsY  s   





z4GeminiRealtimeConfig.return_new_content_delta_eventsc              
   C   s   d}z.d|v r/d|d v r/|d d D ]}d|v r ||d 7 }qd|v r.||d  dd7 }qW n tyF } z
td| d| d }~ww t|dkrNd	nd
ddt |d||dS )Nr   	modelTurnr@   rB   rC   r   z)Error transforming content delta events: z, got message: response.text.deltazresponse.audio.deltar   r   )r|   r   r   r   r   r   r   )rQ   	Exceptionr<   r   r   r	   r   )r8   rv   r   r   rJ   r   rH   er7   r7   r9   transform_content_delta_events  s4   z3GeminiRealtimeConfig.transform_content_delta_eventsdelta_chunkscurrent_output_item_idcurrent_response_idc              	   C   s   |rd dd |D }nd}|d u rdt }|d u r%dt }|dkr9tddd	t |d||d
S |dkrLtddd	t |d|dS d S )Nr   c                 S      g | ]}|d  qS )r   r7   )rk   Zdelta_chunkr7   r7   r9   rl         zEGeminiRealtimeConfig.transform_content_done_event.<locals>.<listcomp>item_{}resp_{}rB   zresponse.text.doner   r   )r|   r   r   r   r   r   rB   rK   zresponse.audio.done)r|   r   r   r   r   r   )r   r   r	   r   r   r   )r8   r   r   r   rJ   r   r7   r7   r9   transform_content_done_event  s6   	z1GeminiRealtimeConfig.transform_content_done_eventdelta_done_eventc           	      C   s   |du rd t }|du rd t }g }ttt |d}tddd t |d|r8|dkr8d|dnd	d
d|d}|| t	dd t d||dddd|r_|dkr_d|dnd	d
dgdd}|| |S )z`
        - return response.content_part.done
        - return response.output_item.done
        Nr   r   rB   zresponse.content_part.doner   r   r   rK   r   r   )r|   r   r   r   r   rH   r   response.output_item.doner   rv   	completedr   r   )r|   r   r   r   r   )
r   r	   r   r   r   rq   rQ   r   r   r   )	r8   r   r   r   rJ   Zreturned_itemsZdelta_done_event_textZresponse_content_part_doneZresponse_output_item_doner7   r7   r9   %return_additional_content_done_events   sX   



z:GeminiRealtimeConfig.return_additional_content_done_eventsobjpathc                 C   s<   | d}| }|D ]}t|tr||v r|| }q	 d S |S )N.)r   rU   r   )r   r   r   currentrt   r7   r7   r9   get_nested_valueA  s   

z%GeminiRealtimeConfig.get_nested_valuetransformed_messagecurrent_delta_chunksc              
   C      zAt |tr&g }d}|D ]}|d dkr|tt| d}q|s#d }|W S |d dkr=|d u r2g }|tt| |W S d }|W S  tyW } z
td| d| d }~ww )NFr|   r   Tz%Error updating current delta chunks: , got transformed_message: )rU   r   r   r   r   r   r<   )r8   r   r   Zany_delta_chunkeventr   r7   r7   r9   update_current_delta_chunksL  s<   
z0GeminiRealtimeConfig.update_current_delta_chunkscurrent_item_chunksc              
   C   r   )NFr|   r   Tz$Error updating current item chunks: r   )rU   r   r   r   r   r   r<   )r8   r   r   Zany_item_chunkr   r   r7   r7   r9   update_current_item_chunksp  s<   
z/GeminiRealtimeConfig.update_current_item_chunkscurrent_conversation_idoutput_itemsc                 C   s   |d u rd t }|d u rd t }|r"t|di }ni }|di }|d}|d}	|ddg}
d	d
 ttt |
D }d|v rRt	j
|d}nt }t|}tdd t td|d|rodd
 |D ng ||| dd}|d ur||d d< |	d ur|	|d d< |S )Nconv_{}r   r   rc   rZ   r   rn   r   c                 S   rh   r7   r   rj   r7   r7   r9   rl     rm   zFGeminiRealtimeConfig.transform_response_done_event.<locals>.<listcomp>ZusageMetadata)Zcompletion_responsezresponse.doner   r   r   c                 S   r   )r   r7   )rk   Zoutput_itemr7   r7   r9   rl     r   )r   r   r   r   r   r\   usager   r   )r   r	   r   r   r   rQ   r   r   rq   r   Z_calculate_usager,   r   Z3_transform_chat_completion_usage_to_responses_usager   r   Z
model_dump)r8   rv   r   r   r   rw   r   r   rZ   r   r   r   Z_chat_completion_usageZresponses_api_usageZresponse_done_eventr7   r7   r9   transform_response_done_event  s`   

z2GeminiRealtimeConfig.transform_response_done_eventopenai_eventr   !realtime_response_transform_inputc                 C   s,  |d }|d }|d }|d }|d }	g }
|t jks |t jkr[|p(dt }|sEdt }|p:dt }| j|	||||d	}
| jtdi |d
 |||d}|
	| n2|t j
kse|t jkr| j||||d}|g}
|dpw|}|dp~|}| j||||d}|
| |
|||||dS )Nr   r   r   r   rw   r   r   r   )rw   r   r   r   rJ   serverContentrJ   )r   r   r   rJ   r   r   )r   r   r   rJ   )returned_messager   r   r   r   current_delta_typer7   )r   rF   rG   r   r	   r   r   r   r   r   rL   rM   r   rQ   r   extend)r8   r   r   r   rJ   r   r   r   r   rw   r   r   Ztransformed_content_done_eventZresolved_item_idZresolved_response_idZadditional_itemsr7   r7   r9   handle_openai_modality_event  sv   

	


z1GeminiRealtimeConfig.handle_openai_modality_eventrt   r   c           	      C   s   | d}| d}d }|r| |}n&|r| j|d}nt D ]\}}||ks5d|v r9t||d ur9|} nq!|d u rHtd| d| |S )Nr   generationCompleter   r   Unknown openai event: z	, value: )rQ   rI   rN   r0   rp   r1   r   r<   )	r8   rt   rS   r   r   Zmodel_turn_eventZgeneration_complete_eventr   Zmap_keyr7   r7   r9   map_openai_event"  s*   


z%GeminiRealtimeConfig.map_openai_eventlogging_objc                    s(  zt |}W n  t jy'   t|tr|jddd}nt|}td| w |j}|d }|d }	|d }
|d }|d	 }|d
 }|d }g }|	d t t
rʈ 	d}t|t
r||	dr||ttddt |d dt dd  	d}t|t
r|	dr|ttddt |d |pdt |	pdt ddd h d}t fdd|D s|||	||
|||dS | D ]\}}| j||||d}|tjkr| |||d	 }t |}|| q|tjkr| jtd&i ||	|
|dd}|| q|tjks'|tjks'|tjks'|tjkrT| j|||d|j v r4dndd }|!|d!  |d }|d }	|d }
|d }|d }qtd"| t"|dkr{t|trp|jddd}nt|}td#| | j#||d$}| j$||d%}|||	||
|||dS )'z
        Keep this state less - leave the state management (e.g. tracking current_output_item_id, current_response_id, current_conversation_id, current_delta_chunks) to the caller.
        rx   r=   ry   r{   r   r   r   r   rw   r   r   r   ZinputTranscriptionrB   z5conversation.item.input_audio_transcription.completedr   r   r   )r|   r   r   r   r   ZoutputTranscriptionzresponse.audio_transcript.deltar   )r|   r   r   r   r   r   r   >   ZturnCompleter   Zinterruptedr   c                 3   s    | ]}| v V  qd S r6   r7   )rk   kZserver_contentr7   r9   	<genexpr>  s    zCGeminiRealtimeConfig.transform_realtime_response.<locals>.<genexpr>)r   r   r   r   r   r   r   rw   )rt   rS   r   r   N)rv   r   r   rw   r   rK   r   r   r   zUnknown message type: )r   r   )r   r   r7   )%r   r   r   rU   r   r   rq   r<   Zlitellm_trace_idrQ   r   r   r   r   r   r	   r   anyrp   r   r   SESSION_CREATEDr   r   RESPONSE_DONEr   r   rF   rL   rG   rM   r   rS   r   rD   r   r   )r8   rv   r3   r   r   r   r   r   r   r   r   r   rw   r   r   r   Zinput_txZ	output_txZ_model_content_keysrt   rS   r   r   Ztransformed_response_done_eventZ_returned_messager7   r   r9   transform_realtime_response@  s   









z0GeminiRealtimeConfig.transform_realtime_responsec                 C   s   dS )NTr7   )r8   r7   r7   r9   requires_session_configuration  s   z3GeminiRealtimeConfig.requires_session_configurationc                 C   s:   dg}d}d| d|ii d}|ri |d< t d|iS )ac  

        ```
        {
            "model": string,
            "generationConfig": {
                "candidateCount": integer,
                "maxOutputTokens": integer,
                "temperature": number,
                "topP": number,
                "topK": integer,
                "presencePenalty": number,
                "frequencyPenalty": number,
                "responseModalities": [string],
                "speechConfig": object,
                "mediaResolution": object
            },
            "systemInstruction": string,
            "tools": [object]
        }
        ```
        ZAUDIOFr~   rn   )r3   rc   ro   ZoutputAudioTranscriptionr   )r   r   )r8   r3   Zresponse_modalitiesZoutput_audio_transcriptionZsetup_configr7   r7   r9   rw     s   z2GeminiRealtimeConfig.session_configuration_requestr6   )rO   )6__name__
__module____qualname__r   rq   r   r:   r>   r'   r   rI   r(   rN   rR   r$   r   rX   r   r`   ru   r   r#   r   r   rV   r   r   r   r   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r*   r)   r   r   r   LiteLLMLoggingObjr+   r   r   rw   r7   r7   r7   r9   r1   C   st   




	

4
K
3


b
"


#
A



$


(

?
Q


 r1   )C__doc__r   typingr   r   r   r   r   r   Zlitellmr   Zlitellm._uuidr	   Z*litellm.litellm_core_utils.litellm_loggingr
   r   Z-litellm.llms.base_llm.realtime.transformationr   rr   r   ZBlitellm.responses.litellm_completion_transformation.transformationr   Zlitellm.types.llms.geminir   r   r   r   r   r   Zlitellm.types.llms.openair   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   Zlitellm.types.llms.vertex_air%   r&   r'   Zlitellm.types.realtimer(   r)   r*   r+   Zlitellm.utilsr,   Zcommon_utilsr.   r/   r   rL   r   r0   rq   __annotations__r1   r7   r7   r7   r9   <module>   s*      H