o
    ưi{                     @   s   d dl Z d dlmZmZ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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mZmZm Z m!Z!m"Z" G dd	 d	eZ#G d
d dZ$dS )    N)AnyAsyncIteratorDictIteratorListOptionalUnioncast)verbose_loggernormalize_tool_schema)AllMessageValuesChatCompletionAssistantMessageChatCompletionAssistantToolCallChatCompletionImageObjectChatCompletionRequestChatCompletionSystemMessageChatCompletionTextObject#ChatCompletionToolCallFunctionChunkChatCompletionToolChoiceValuesChatCompletionToolMessageChatCompletionToolParamChatCompletionUserMessage)GenericLiteLLMParams)AdapterCompletionStreamWrapperChoicesModelResponseModelResponseStreamStreamingChoicesc                       s   e Zd ZU dZdZeed< eeeee	f f ed< de	f fddZ
dd	 Zd
d Zdee fddZdee fddZ  ZS )GoogleGenAIStreamWrapperz
    Wrapper for streaming Google GenAI generate_content responses.
    Transforms OpenAI streaming chunks to Google GenAI format.
    Fsent_first_chunkaccumulated_tool_callscompletion_streamc                    s"   d| _ i | _d| _t | d S )NF)r    r!   _returned_responsesuper__init__)selfr"   	__class__ c/home/app/Keep/.python/lib/python3.10/site-packages/litellm/google_genai/adapters/transformation.pyr%   (   s   z!GoogleGenAIStreamWrapper.__init__c                 C   s   z5t | jds| jrtd| _t | jW S | jD ]}|dks$|d u r%qt || }|r3|  W S qt ty=     tyE   tw )N__iter__TNone)hasattrr"   r#   StopIterationGoogleGenAIAdapter(translate_completion_to_generate_content2translate_streaming_completion_to_generate_content	Exception)r&   chunktransformed_chunkr)   r)   r*   __next__.   s.   

z!GoogleGenAIStreamWrapper.__next__c           	         sr  zt | jds| jrtd| _t | jW S | j2 z3 d H W }|dks)|d u r*qt || }|r8|  W S q6 | jrzcg }| j D ];\}}zt	
|d pQd}d|d pYd|d	i}|| W qE t	jy   td
| d|d  d|d   Y qEw |rd|ddddg dgi}|W | j  W S W | j  t| j  w t ty     ty   tw )N	__aiter__Tr,   	argumentsz{}functionCallnameundefined_tool_namer9   argsz?Could not parse tool call arguments at end of stream for index z. Name: z. Partial args: 
candidatesmodelpartsroleSTOPr   contentZfinishReasonindexZsafetyRatings)r-   r"   r#   StopAsyncIterationr/   r0   r1   r!   itemsjsonloadsappendJSONDecodeErrorr
   warningclearr2   )	r&   r3   r4   r@   tool_call_indexZtool_call_dataparsed_argsfunction_call_partZfinal_chunkr)   r)   r*   	__anext__H   s   



z"GoogleGenAIStreamWrapper.__anext__returnc                 c   s@    | j D ]}t|trdt| d}| V  q|V  qdS )zU
        Convert Google GenAI streaming chunks to Server-Sent Events format.
        data: 

N)r"   
isinstancedictrH   dumpsencode)r&   r3   payloadr)   r)   r*   google_genai_sse_wrapper   s   

z1GoogleGenAIStreamWrapper.google_genai_sse_wrapperc                 C  s   ddl m} | j2 zM3 dH W }t|tr$dt| d}| V  q
t||rEt 	|| }t|trDdt| d}| V  q
q
t
|drP| V  q
t| V  q
6 dS )z<
        Async version of google_genai_sse_wrapper.
        r   )r   NrS   rT   rX   )litellm.types.utilsr   r"   rU   rV   rH   rW   rX   r/   r1   r-   str)r&   r   r3   rY   r4   r)   r)   r*   async_google_genai_sse_wrapper   s$   



z7GoogleGenAIStreamWrapper.async_google_genai_sse_wrapper)__name__
__module____qualname____doc__r    bool__annotations__r   r\   r   r%   r5   rQ   r   bytesrZ   r   r]   __classcell__r)   r)   r'   r*   r      s   
 Gr   c                   @   s  e Zd ZdZd-ddZ		d.dedeeeee	f  eee	f f de
eee	f  d	e
e deee	f f
d
dZ	d/deee	f d	e
e defddZde	deee df fddZdeeee	f  dee fddZdeee	f de
e fddZ	d/deeee	f  de
eee	f  dee fddZdedeee	f fddZdeeef dede
eee	f  fdd Zd!e	deeee	f  fd"d#Zd$e	dedeeee	f  fd%d&Zd'e
e defd(d)Zd*e	deee f fd+d,Z!dS )0r/   zaAdapter for transforming Google GenAI generate_content requests to/from litellm.completion formatrR   Nc                 C   s   d S Nr)   )r&   r)   r)   r*   r%      s   zGoogleGenAIAdapter.__init__r>   contentsconfiglitellm_paramsc                 K   s&  | dp	| d}| d}| dp| d}t|tr"|g}	n|}	| j|	|d}
||
d}|r_d|v r<|d |d< d	|v rF|d	 |d
< d|v rP|d |d< d|v rU	 d|v r_|d |d< |rwt|trwt|dkrw| |}|rw||d< |r| |}|r||d< t|}|r| j||d}|S )ax  
        Transform generate_content request to litellm completion format

        Args:
            model: The model name
            contents: Generate content contents (can be list or single dict)
            config: Optional config parameters
            **kwargs: Additional parameters from the original request

        Returns:
            Dict in OpenAI format
        ZsystemInstructionsystem_instructiontoolsZ
toolConfigtool_config)rj   )r>   messagesZtemperatureZmaxOutputTokensZ
max_tokensZtopPZtop_pZtopKZstopSequencesstopr   tool_choice)completion_request_dictri   )	getrU   rV   _transform_contents_to_messageslistlen'_transform_google_genai_tools_to_openai-_transform_google_genai_tool_config_to_openai&_add_generic_litellm_params_to_request)r&   r>   rg   rh   ri   kwargsrj   rk   rl   Zcontents_listrm   Zcompletion_requestopenai_toolsro   rp   r)   r)   r*   (translate_generate_content_to_completion   sV   


z;GoogleGenAIAdapter.translate_generate_content_to_completionrp   c                 C   s@   t j }|r|jdd}| D ]\}}||v r|||< q|S )zAdd generic litellm params to request. e.g add api_base, api_key, api_version, etc.

        Args:
            completion_request_dict: Dict[str, Any]
            litellm_params: GenericLiteLLMParams

        Returns:
            Dict[str, Any]
        T)Zexclude_none)r   Zmodel_fieldskeysZ
model_dumprG   )r&   rp   ri   Zallowed_fieldsZlitellm_dictkeyvaluer)   r)   r*   rw   $  s   
z9GoogleGenAIAdapter._add_generic_litellm_params_to_requestr"   c                 C   s   t |d}| S )z<Transform streaming completion output to Google GenAI format)r"   )r   r]   )r&   r"   Zgoogle_genai_wrapperr)   r)   r*   ,translate_completion_output_params_streaming:  s   z?GoogleGenAIAdapter.translate_completion_output_params_streamingrk   c                 C   s   g }|D ]3}d|v r7|d D ](}d| ddi}d|v r"|d |d< d|v r,|d |d< d|d}|| qqd	d
 |D }ttt |S )z3Transform Google GenAI tools to OpenAI tools formatZfunctionDeclarationsr9    descriptionZparametersJsonSchema
parametersfunction)typer   c                 S   s   g | ]}t |qS r)   r   ).0toolr)   r)   r*   
<listcomp>\  s    zNGoogleGenAIAdapter._transform_google_genai_tools_to_openai.<locals>.<listcomp>)rq   rJ   r	   r   r   )r&   rk   ry   r   Z	func_declZfunction_chunkZopenai_toolZnormalized_toolsr)   r)   r*   ru   E  s   
z:GoogleGenAIAdapter._transform_google_genai_tools_to_openairl   c                 C   s:   | di }| dd}dddd}| |d}tt|S )z8Transform Google GenAI tool_config to OpenAI tool_choiceZfunctionCallingConfigmodeAUTOautorequirednone)r   ANYNONE)rq   r	   r   )r&   rl   Zfunction_calling_configr   Zmode_mappingro   r)   r)   r*   rv   `  s
   
z@GoogleGenAIAdapter._transform_google_genai_tool_config_to_openairj   c                 C   s  g }|r| dg }|rd|d v r|td|d d d |D ]=}| dd}| dg }|dkrg }g }	|D ]t}
t|
trd|
v rS|ttd|
d d q:d	|
v r{|
d	 }| d
d}| dd}|ttddd| d| id q:d|
v r|
d }tdd| dd t	
| di d}|	| q:t|
tr|ttd|
d q:|rt|dkrt|d tr|d  ddkrtt|d }|td|d d n	|td|d ||	 q!|dkr_d}g }|D ]J}
t|
tr4d|
v r||
d 7 }qd|
v r3|
d }td| dd dt| ddt	
| di d d!}|| qt|
tr>||
7 }q|rOtd"|rI|nd#|d$}ntd"|rV|nd#d}|| q!|S )%z9Transform Google GenAI contents to OpenAI messages formatr@   textr   system)rA   rD   rA   user)r   r   inline_data	mime_typez
image/jpegdatar   	image_urlurlzdata:z;base64,)r   r   ZfunctionResponser   Zcall_r9   unknownresponse)rA   Ztool_call_idrD      r   r>   r8   r   r<   r9   r7   )idr   r   Z	assistantN)rA   rD   
tool_calls)rq   rJ   r   rU   rV   r	   r   r   r   rH   rW   r\   rt   r   extendr   r   r   )r&   rg   rj   rm   Zsystem_partsrD   rA   r@   Zcontent_partsZtool_messagespartr   r   r   Zfunc_responseZtool_messageZ	text_partZcombined_textr   	func_call	tool_callZassistant_messager)   r)   r*   rr   m  s   










z2GoogleGenAIAdapter._transform_contents_to_messagesr   c                 C   s  |j r|j d nd}|stdt|tr#|jstd| |j}nt|di ddp6t|di dd}|r>d	|igng }|d
d| t|dddg dgt	|dret|ddre| 
t|ddnddddd}d}|D ]}t|trd	|v r||d	 7 }qq|r||d	< |S )z
        Transform litellm completion response to Google GenAI generate_content format

        Args:
            response: ModelResponse from litellm.completion

        Returns:
            Dict in Google GenAI generate_content response format
        r   Nz-Invalid completion response: no choices foundz7Invalid completion response: no message found in choicemessagerD   r   deltar   r>   r?   finish_reasonrC   usageZpromptTokenCountZcandidatesTokenCountZtotalTokenCount)r=   usageMetadata)choices
ValueErrorrU   r   r   /_transform_openai_message_to_google_genai_partsgetattrrq   _map_finish_reasonr-   
_map_usagerV   )r&   r   choicer@   message_contentZgenerate_content_responsetext_contentr   r)   r)   r*   r0     sP   


z;GoogleGenAIAdapter.translate_completion_to_generate_contentwrapperc                 C   s0  |j r|j d nd}|sdS t|tr'|jr| |j|}ng }t|dd}nt|di dd}|r8d|igng }t|dd}|sF|sFdS d|d	d
|rR| |nddg dgi}|rzt|drpt|ddrp| 	t|ddndddd}||d< d}	|D ]}
t|
t
rd|
v r|	|
d 7 }	q~|	r|	|d< |S )aV  
        Transform streaming litellm completion chunk to Google GenAI generate_content format

        Args:
            response: Streaming ModelResponse chunk from litellm.completion
            wrapper: GoogleGenAIStreamWrapper instance

        Returns:
            Dict in Google GenAI streaming generate_content response format
        r   Nr   r   rD   r   r   r=   r>   r?   rC   r   r   r   )r   rU   r   r   ?_transform_openai_delta_to_google_genai_parts_with_accumulationr   rq   r   r-   r   rV   )r&   r   r   r   r@   r   r   Zstreaming_chunkZusage_metadatar   r   r)   r)   r*   r1   7  sX   

	zEGoogleGenAIAdapter.translate_streaming_completion_to_generate_contentr   c              	   C   s   g }t |dr|jr|d|ji t |drT|jrT|jD ]6}t |drS|jrSz|jjr3t|jjni }W n tjyB   i }Y nw d|jj	pId|di}|| q|rX|S ddigS )	z5Transform OpenAI message to Google GenAI parts formatrD   r   r   r   r8   r:   r;   r   )
r-   rD   rJ   r   r   r7   rH   rI   rK   r9   )r&   r   r@   r   r<   rP   r)   r)   r*   r     s,   


zBGoogleGenAIAdapter._transform_openai_message_to_google_genai_partsr   c              	   C   sJ  t |dsi |_g }t |dr|jr|d|ji |jpg }|D ]}t |ds)q!t|dd}|du r4q!||jvrAddd|j|< t|jd	d}t|jd
d}|s\|s\td|  q!|re||j| d	< |rr|j| d
  |7  < |j| }	|	d	 }
|	d
 }zt	
|}|
rd|
|di}|| |j|= W q! t	jy   Y q!w |S )zQTransforms OpenAI delta to Google GenAI parts, accumulating streaming tool calls.r!   rD   r   r   rE   Nr   r   r9   r7   z*Skipping empty tool call chunk for index: r8   r;   )r-   r!   rD   rJ   r   r   r   r
   debugrH   rI   rK   )r&   r   r   r@   r   r   rN   Zfunction_nameZ
args_chunkZaccumulated_dataZaccumulated_nameZaccumulated_argsrO   rP   r)   r)   r*   r     s\   







zRGoogleGenAIAdapter._transform_openai_delta_to_google_genai_parts_with_accumulationr   c                 C   s(   |sdS dddddddd}| |dS )z8Map OpenAI finish reasons to Google GenAI finish reasonsrB   Z
MAX_TOKENSZSAFETYZFINISH_REASON_UNSPECIFIEDZMALFORMED_FUNCTION_CALL)rn   lengthZcontent_filterr   Zfunction_callZfinish_reason_unspecifiedZmalformed_function_call)rq   )r&   r   mappingr)   r)   r*   r     s   
z%GoogleGenAIAdapter._map_finish_reasonr   c                 C   s0   t |ddpdt |ddpdt |ddpddS )z-Map OpenAI usage to Google GenAI usage formatZprompt_tokensr   Zcompletion_tokensZtotal_tokensr   )r   )r&   r   r)   r)   r*   r     s   zGoogleGenAIAdapter._map_usage)rR   N)NNrf   )"r^   r_   r`   ra   r%   r\   r   r   r   r   r   r   rz   rV   rw   r   rd   r~   r   ru   r   rv   r   rr   r   r0   r   r   r1   r   r   r   intr   r)   r)   r)   r*   r/      s    


i






 	

B

P
"
Qr/   )%rH   typingr   r   r   r   r   r   r   r	   Zlitellmr
   Z/litellm.litellm_core_utils.json_validation_ruler   Zlitellm.types.llms.openair   r   r   r   r   r   r   r   r   r   r   r   Zlitellm.types.routerr   r[   r   r   r   r   r   r   r/   r)   r)   r)   r*   <module>   s    (8	 