
    i1{                         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	e      Z# G d
 d      Z$y)    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                        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Z
d Zd Zd	ee   fd
Zd	ee   fdZ x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                 N    d| _         i | _        d| _        t        |   |       y )NF)r!   r"   _returned_responsesuper__init__)selfr#   	__class__s     }/Users/manta/Documents/Projects/TheRoad-I1/.venv/lib/python3.12/site-packages/litellm/google_genai/adapters/transformation.pyr'   z!GoogleGenAIStreamWrapper.__init__(   s)     %&(#"'*+    c                 ^   	 t        | j                  d      s<| j                  rt        d| _        t	               j                  | j                        S | j                  D ]*  }|dk(  s|t	               j                  ||       }|s(|c S  t        # t        $ r  t        $ r t        w xY w)N__iter__TNone)hasattrr#   r%   StopIterationGoogleGenAIAdapter(translate_completion_to_generate_content2translate_streaming_completion_to_generate_content	Exception)r(   chunktransformed_chunks      r*   __next__z!GoogleGenAIStreamWrapper.__next__.   s    	 411:>**''*.')+TT**  //F?em$6$8$k$k4%! %,, 0   	 	 	 s   AB 3B B B B,c                   K   	 t        | j                  d      s<| j                  rt        d| _        t	               j                  | j                        S | j                  2 3 d {   }|dk(  s|t	               j                  ||       }|s.|c S 7 -6 | j                  r		 g }| j                  j                         D ]~  \  }}	 t        j                  |d   xs d      }d|d   xs d|d	i}|j                  |       C# t        j                  $ r' t        j                  d
| d|d    d|d           Y |w xY w |r)d|ddddg dgi}|| j                  j                          S 	 | j                  j                          t        # | j                  j                          w xY wt        # t        $ r  t         $ r t        w xY ww)N	__aiter__Tr.   	argumentsz{}functionCallnameundefined_tool_namer<   argsz?Could not parse tool call arguments at end of stream for index z. Name: z. Partial args: 
candidatesmodelpartsroleSTOPr   contentfinishReasonindexsafetyRatings)r/   r#   r%   StopAsyncIterationr1   r2   r3   r"   itemsjsonloadsappendJSONDecodeErrorr   warningclearr4   )	r(   r5   r6   rC   tool_call_indextool_call_dataparsed_argsfunction_call_partfinal_chunks	            r*   	__anext__z"GoogleGenAIStreamWrapper.__anext__H   s$    D	%411;?**,,*.')+TT**   $55 -eF?em$6$8$k$k4%! %,,-5 ***8E 44::<'&! +/** .{ ; Ct+K !/,:6,B -='<,71"2. "LL);<#33 !*22"abqar s))7)?(@ A11?1L0M!O
 !! =. (9>/P4:-.57	!"+	'  + //557  //557$$ //557$$! 	 	%$$	%s   GAF3 GF3 "B&B'B*%F3 F3 GBF3 %"F ;DF 7D>;F =D>>F F3 ,G. F3 F**	F3 3GGreturnc              #      K   | j                   D ]B  }t        |t              r,dt        j                  |       d}|j                          ?| D yw)zU
        Convert Google GenAI streaming chunks to Server-Sent Events format.
        data: 

N)r#   
isinstancedictrM   dumpsencode)r(   r5   payloads      r*   google_genai_sse_wrapperz1GoogleGenAIStreamWrapper.google_genai_sse_wrapper   sL      ++E%&"4::e#4"5T:nn&& ,s   AAc                  K   ddl m} | j                  2 3 d{   }t        |t              r-dt        j                  |       d}|j                          Ft        ||      rXt               j                  ||       }t        |t              r-dt        j                  |       d}|j                          t        |d      r|j                          t        |      j                          7 6 yw)z<
        Async version of google_genai_sse_wrapper.
        r   )r   Nr[   r\   r`   )litellm.types.utilsr   r#   r]   r^   rM   r_   r`   r1   r3   r/   str)r(   r   r5   ra   r6   s        r*   async_google_genai_sse_wrapperz7GoogleGenAIStreamWrapper.async_google_genai_sse_wrapper   s      	<11 	.%%&"4::e#4"5T:nn&&E#67$6$8$k$k4%! /6 &tzz2C'D&ETJG!..**  5(+,,.(e*++--+	.1s&   D C>C<C>CD <C>>D )__name__
__module____qualname____doc__r!   bool__annotations__r   re   r   r'   r7   rX   r   bytesrb   r   rf   __classcell__)r)   s   @r*   r    r       sf    
 #d" d38n!455,# , 4E%N	(5/ 	.mE6J .r+   r    c                      e Zd ZdZ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	Z	 d"d
eee	f   de
e   defdZde	deee   df   fdZdeeee	f      dee   fdZdeee	f   de
e   fdZ	 d"deeee	f      de
eee	f      dee   fdZdedeee	f   fdZdeeef   dede
eee	f      fdZde	deeee	f      fdZde	dedeeee	f      fdZde
e   defdZde	deee f   fdZ!y)#r1   zaAdapter for transforming Google GenAI generate_content requests to/from litellm.completion formatrY   Nc                      y N )r(   s    r*   r'   zGoogleGenAIAdapter.__init__   s    r+   rA   contentsconfiglitellm_paramsc                 f   |j                  d      xs |j                  d      }|j                  d      }|j                  d      xs |j                  d      }t        |t              r|g}	n|}	| j                  |	|      }
||
d}|r5d|v r|d   |d<   d	|v r|d	   |d
<   d|v r|d   |d<   d|v r	 d|v r|d   |d<   |r6t        |t              r&t        |      dkD  r| j                  |      }|r||d<   |r| j                  |      }|r||d<   t        |      }|r| j                  ||      }|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
        systemInstructionsystem_instructiontools
toolConfigtool_config)rx   )rA   messagestemperaturemaxOutputTokens
max_tokenstopPtop_ptopKstopSequencesstopr   tool_choice)completion_request_dictru   )	getr]   r^   _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(   rA   rs   rt   ru   kwargsrx   ry   r{   contents_listr|   completion_requestopenai_toolsr   r   s                  r*   (translate_generate_content_to_completionz;GoogleGenAIAdapter.translate_generate_content_to_completion   s   , $ZZ(;< 


 A
 

7#jj.K&**]2K h%%JM$M 77.@ 8 
  5
$ &4:=4I"=1 F*39:K3L"<0.4Vn"7+&(-3O-D"6* %&3u:>#KKER2>&w/ LLK 4?"=1
 #''9":&*&Q&Q(?- 'R '#
 '&r+   r   c                     t         j                  j                         }|r4|j                  d      }|j	                         D ]  \  }}||v s|||<    |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)exclude_none)r   model_fieldskeys
model_dumprL   )r(   r   ru   allowed_fieldslitellm_dictkeyvalues          r*   r   z9GoogleGenAIAdapter._add_generic_litellm_params_to_request$  s`     .::??A)44$4GL*002
U.(38+C0 3 '&r+   r#   c                 :    t        |      }|j                         S )z<Transform streaming completion output to Google GenAI format)r#   )r    rf   )r(   r#   google_genai_wrappers      r*   ,translate_completion_output_params_streamingz?GoogleGenAIAdapter.translate_completion_output_params_streaming:  s#    
  8/ 
 $BBDDr+   ry   c                    g }|D ]S  }d|v s|d   D ]D  }d|j                  dd      i}d|v r|d   |d<   d|v r|d   |d<   d|d}|j                  |       F U |D cg c]  }t        |       }}t        t        t
           |      S c c}w )	z3Transform Google GenAI tools to OpenAI tools formatfunctionDeclarationsr<    descriptionparametersJsonSchema
parametersfunction)typer   )r   rO   r   r
   r   r   )r(   ry   r   tool	func_declfunction_chunkopenai_toolnormalized_toolss           r*   r   z:GoogleGenAIAdapter._transform_google_genai_tools_to_openaiE  s    
 .0D%-!%&<!=I	fb 96N %	18A-8P}5-:7@AW7X|4+5>"RK ''4 ">   EQQLD1$7LQD013CDD Rs   B
r{   c                     |j                  di       }|j                  dd      }dddd}|j                  |d      }t        t        |      S )z8Transform Google GenAI tool_config to OpenAI tool_choicefunctionCallingConfigmodeAUTOautorequirednone)r   ANYNONE)r   r
   r   )r(   r{   function_calling_configr   mode_mappingr   s         r*   r   z@GoogleGenAIAdapter._transform_google_genai_tool_config_to_openai`  sT    
 #.//2I2"N&**66: &z6J"&&tV42K@@r+   rx   c                 z   g }|r=|j                  dg       }|r)d|d   v r"|j                  t        d|d   d                |D ]  }|j                  dd      }|j                  dg       }|dk(  rg }g }	|D ])  }
t        |
t              rd|
v r&|j                  t        t        d|
d   d             >d	|
v rT|
d	   }|j                  d
d      }|j                  dd      }|j                  t        t        ddd| d| id             d|
v s|
d   }t        dd|j                  dd       t        j                  |j                  di                   }|	j                  |       t        |
t              s|j                  t        t        d|
d             , |rt        |      dk(  r]t        |d   t              rJ|d   j                  d      dk(  r3t        t        |d         }|j                  t        d|d                n|j                  t        d|             |j                  |	       |dk(  sd}g }|D ]  }
t        |
t              rd|
v r	||
d   z  } d|
v s%|
d   }t        d|j                  dd       dt!        |j                  dd      t        j                  |j                  di                    !      }|j                  |       t        |
t              s||
z  } |rt#        d"|r|nd#|$      }nt#        d"|r|nd#      }|j                  |        |S )%z9Transform Google GenAI contents to OpenAI messages formatrC   textr   system)rD   rG   rD   user)r   r   inline_data	mime_typez
image/jpegdatar   	image_urlurlzdata:z;base64,)r   r   functionResponser   call_r<   unknownresponse)rD   tool_call_idrG      r   rA   r;   r   r?   r<   r:   )idr   r   	assistantN)rD   rG   
tool_calls)r   rO   r   r]   r^   r
   r   r   r   rM   r_   re   r   r   extendr   r   r   )r(   rs   rx   r|   system_partsrG   rD   rC   content_partstool_messagespartr   r   r   func_responsetool_message	text_partcombined_textr   	func_call	tool_callassistant_messages                         r*   r   z2GoogleGenAIAdapter._transform_contents_to_messagesm  su    ,. -11'2>L,q/ 9/%|Av/F  G;;vv.DKK,Ev~   BD!D!$-!T>)00 $$<-3T&\$J!" +d2*.}*=K(3\(RI#.??62#>D)00 $$=0;,1U9+XdV3T6*%&!"
 047,01C,DM+D%+/4]5F5Fvy5Y4Z-[(,

=3D3DZQS3T(U,L
 *00>#D#.%,,  86SW:XG "T ! M*a/&}Q'7>)!,008FB$()A=QRCS$T	 5%+Yv5F !5%+] . "DF
!D!$-!T>)T&\9M+t3(,^(<I(G%*9==+K*L#M%/)L)2vr)B.2jjvr9R.S*")I '--i8#D#.%-# "( (F(1>D#-)% )G(1>D)%
  12e  h r+   r   c                    |j                   r|j                   d   nd}|st        d      t        |t              r3|j                  st        d      | j                  |j                        }nEt        |di       j                  dd      xs t        |di       j                  dd      }|rd	|igng }|d
d| j                  t        |dd            dg dgt        |d      r)t        |dd      r| j                  t        |dd            nddddd}d}|D ]   }t        |t              sd	|v s||d	   z  }" |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messagerG   r   deltar   rA   rB   finish_reasonrF   usagepromptTokenCountcandidatesTokenCounttotalTokenCount)r@   usageMetadata)choices
ValueErrorr]   r   r   /_transform_openai_message_to_google_genai_partsgetattrr   _map_finish_reasonr/   
_map_usager^   )r(   r   choicerC   message_contentgenerate_content_responsetext_contentr   s           r*   r2   z;GoogleGenAIAdapter.translate_completion_to_generate_content  s}    )1(8(8!!!$dLMM fg&>> M  HHXE &fi<@@2 A"-11)R@  4Cfo./E */@$($;$;>% %'	 8W-'(GT2R '4 @A )*,-'(5
!. D$%&D.V,  0<%f-((r+   wrapperc                 h   |j                   r|j                   d   nd}|syt        |t              r9|j                  r| j	                  |j                  |      }ng }t        |dd      }n3t        |di       j                  dd      }|rd|igng }t        |dd      }|s|syd|d	d
|r| j                  |      nddg dgi}|r@t        |d      r)t        |dd      r| j                  t        |dd            ndddd}||d<   d}	|D ]   }
t        |
t              sd|
v s|	|
d   z  }	" |	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   rG   r   r   r@   rA   rB   rF   r   r   r   )r   r]   r   r   ?_transform_openai_delta_to_google_genai_parts_with_accumulationr   r   r   r/   r   r^   )r(   r   r   r   rC   r   r   streaming_chunkusage_metadatar   r   s              r*   r3   zEGoogleGenAIAdapter.translate_streaming_completion_to_generate_content7  s   " )1(8(8!!!$d f./||\\LL' #FOTBM &fgr:>>y"MO3Bfo./E#FOTBM ] ).@ ) //>!%'	+
   8W-'(GT2R '4 @A )*,-'(  0>OO, D$%&D.V,  &2OF#r+   r   c                 "   g }t        |d      r)|j                  r|j                  d|j                  i       t        |d      r|j                  r|j                  D ]  }t        |d      s|j                  s	 |j                  j
                  r)t        j                  |j                  j
                        ni }d|j                  j                  xs d|di}|j                  |        |r|S ddigS # t        j                  $ r i }Y Rw xY w)	z5Transform OpenAI message to Google GenAI parts formatrG   r   r   r   r;   r=   r>   r   )
r/   rG   rO   r   r   r:   rM   rN   rP   r<   )r(   r   rC   r   r?   rV   s         r*   r   zBGoogleGenAIAdapter._transform_openai_message_to_google_genai_parts  s   
 ') 7I&7??LL&'//23 7L)g.@.@$//	9j1i6H6H"  )11;; !JJy'9'9'C'CD!#  '$-$6$6$;$;$T?T$()*& LL!34# 0& u1VRL>1  // "!"s   :AC66DDr   c                    t        |d      si |_        g }t        |d      r)|j                  r|j                  d|j                  i       |j                  xs g }|D ]  }t        |d      st        |dd      }|!||j                  vrddd|j                  |<   t        |j                  d	d      }t        |j                  d
d      }|s|st        j                  d|        |r||j                  |   d	<   |r|j                  |   d
xx   |z  cc<   |j                  |   }	|	d	   }
|	d
   }	 t        j                  |      }|
r%d|
|di}|j                  |       |j                  |=  |S # t        j                  $ r Y -w xY w)zQTransforms OpenAI delta to Google GenAI parts, accumulating streaming tool calls.r"   rG   r   r   rI   Nr   r   r<   r:   z*Skipping empty tool call chunk for index: r;   r>   )r/   r"   rG   rO   r   r   r   r   debugrM   rN   rP   )r(   r   r   rC   r   r   rS   function_name
args_chunkaccumulated_dataaccumulated_nameaccumulated_argsrU   rV   s                 r*   r   zRGoogleGenAIAdapter._transform_openai_delta_to_google_genai_parts_with_accumulation  s    w 89-/G*&(5)$LL&%--01 %%+
#I9j1 &i$?O& g&D&DD!#C..? $I$6$6EM !3!3[$GJ !$$@@QR JW..?G..?  
  '==oN/7/<"jj)9: $ '1A;(W*& LL!34  66Go $|  ''  s   3<E44F
Fr   c                 <    |sydddddd}|j                  |d      S )z8Map OpenAI finish reasons to Google GenAI finish reasonsrE   
MAX_TOKENSSAFETY)r   lengthcontent_filterr   function_call)r   )r(   r   mappings      r*   r   z%GoogleGenAIAdapter._map_finish_reason  s3     "& #
 {{=&11r+   r   c                 h    t        |dd      xs dt        |dd      xs dt        |dd      xs ddS )z-Map OpenAI usage to Google GenAI usage formatprompt_tokensr   completion_tokenstotal_tokensr   )r   )r(   r   s     r*   r   zGoogleGenAIAdapter._map_usage	  sB     !( B Ga$+E3F$J$Oa&una@EA
 	
r+   )rY   N)NNrq   )"rg   rh   ri   rj   r'   re   r	   r   r   r   r   r   r   r^   r   r   rm   r   r   r   r   r   r   r   r   r2   r   r    r3   r   r   r   intr   rr   r+   r*   r1   r1      sl   k ,09=d'd' T#s(^,d38n<=d' c3h(	d'
 !!56d' 
c3hd'R :>'!%c3h' !!56' 
	',	E	E 
}U#T)	*	EEDcN#E 
%	&E6A#s(^A 
0	1A  8<FtCH~&F %T#s(^4F 
		FP@)@) 
c3h@)DN'::;N *N 
$sCx.	!	N` 2 2 
d38n	 2DOO#;O	d38n	Ob2 2# 2
 
S#X 
r+   r1   )%rM   typingr   r   r   r   r   r   r	   r
   litellmr   /litellm.litellm_core_utils.json_validation_ruler   litellm.types.llms.openair   r   r   r   r   r   r   r   r   r   r   r   litellm.types.routerr   rd   r   r   r   r   r   r    r1   rr   r+   r*   <module>r     sV     R R R " Q    6 W.= W.tW	
 W	
r+   