
    ^hMH                        S r SSKrSSKJrJrJrJrJrJrJ	r	  SSK
r
SSKJr  SSKrSSKJr  SSKJrJrJrJr  SSKJrJr  SSKJrJrJr  SS	KJrJrJrJ r   SS
K!7  SSK!J"r"J#r#J$r$J%r%J&r&J'r'J(r(  SSK)J*r*J+r+J,r,  \(       a	  SSK-J.r/  \/r0O\1r0S\2S\#4S jr3S\2S\\2   4S jr4S\\   S\\5   4S jr6S\\   S\2S\7S\S   S\7S\\2   S\$4S jr8S\\2   S\\   S\\2   S\2S\\   S \\\9\
Rt                  4      S!\\7   S\7S"\0S\S   S\7S\$4S# jr;S\\2   S\\   S\\2   S\2S\\   S \\\9\
Rt                  4      S!\\7   S\7S"\Rx                  Rz                  R\                  S\S   S\7S\$4S$ jr>S%\?S\\   S\\\&   \\   4   4S& jr@g)'z}
Transformation logic from OpenAI format to Gemini format. 

Why separate file? Make it easy to see how transformation works
    N)TYPE_CHECKINGListLiteralOptionalTupleUnioncast)	BaseModel)verbose_logger)convert_to_anthropic_image_obj"convert_to_gemini_tool_call_invoke"convert_to_gemini_tool_call_resultresponse_schema_prompt)AsyncHTTPHandlerHTTPHandler) get_file_mime_type_for_file_typeget_file_type_from_extension is_gemini_1_5_accepted_file_type)AllMessageValuesChatCompletionAssistantMessageChatCompletionImageObjectChatCompletionTextObject)*)GenerationConfigPartTypeRequestBodySafetSettingsConfigSystemInstructions
ToolConfigTools   )_check_text_in_contentget_supports_response_schemaget_supports_system_message)Logging	image_urlreturnc                     SU ;   am  [         R                  R                  U 5      S   nUSS n[        U5      n[	        U5      (       d  [        SU 35      e[        U5      n[        X@S9n[        US9$ SU ;   a   [        U 5      =nb  [        XS	9n[        US9$ SU ;   d  S
U ;   a$  [        U 5      n[        US   US   S9n[        US9$ [        SR                  U 5      5      e! [
         a  n	U	eSn	A	ff = f)z@
Given an image URL, return the appropriate PartType for Gemini
zgs://   Nz$File type not supported by gemini - )	mime_typefile_uri)	file_datazhttps://)r,   r+   base64data
media_type)r/   r+   )inline_datazInvalid image received - {})ospathsplitextr   r   	Exceptionr   FileDataTyper   _get_image_mime_type_from_urlr   BlobTypeformat)
r&   extension_with_dot	extension	file_typer+   r-   
image_typeimage_blobes
             f/home/james-whalen/.local/lib/python3.13/site-packages/litellm/llms/vertex_ai/gemini/transformation.py_process_gemini_imagerB   :   s   i!#!1!1)!<R!@*12.I4Y?I 4I>>"Fyk RSS8CI$yMIi00)#<YGGT$iNIi009$I(=29=E%-5;NOE..5<<YGHH s*   A2C% 5%C% /C% C% %
C6/C11C6urlc                 
   U R                  5       n U R                  S5      (       a  gU R                  S5      (       a  gU R                  S5      (       a  gU R                  S5      (       a  gU R                  S	5      (       a  g
g)aF  
Get mime type for common image URLs
See gemini mime types: https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/image-understanding#image-requirements

Supported by Gemini:
 - PNG (`image/png`)
 - JPEG (`image/jpeg`)
 - WebP (`image/webp`)
Example:
    url = https://example.com/image.jpg
    Returns: image/jpeg
)z.jpgz.jpegz
image/jpegz.pngz	image/pngz.webpz
image/webpz.mp4z	video/mp4z.pdfzapplication/pdfN)lowerendswith)rC   s    rA   r7   r7   _   sm     ))+C
||%&&	f			g			f			f		     messagesc                 	   SS1n/ nSnSn/ n U[        U 5      :  Ga(  / nUnU[        U 5      :  Gad  X   S   U;   GaX  X   R                  S5      nUb  [        U[        5      (       a  / n	U H  n
U
S   S:X  aG  SU
;   aA  [        U
S   5      S:  a/  [	        [
        U
5      n
[        U
S   S	9nU	R                  U5        MS  U
S   S
:X  d  M^  [	        [        U
5      n
U
n[        US
   [        5      (       a	  US
   S   nOUS
   n[        US9nU	R                  U5        M     UR                  U	5        OAUb>  [        U[        5      (       a)  [        U5      S:  a  [        US	9nUR                  U5        US-  nU[        U 5      :  a  X   S   U;   a  GMX  U(       aX   [        U5      nUSL a.  [        R                  " S5        UR                  [        SS	95        UR                  [!        SUS95        / nU[        U 5      :  Gag  X   S   S:X  Ga[  [        X   ["        5      (       a  X   R%                  5       nOX   n['        S0 UD6nUR                  SS5      nUbq  [        U[        5      (       a\  / n	U HB  n
[        U
[        5      (       d  M  U
S   S:X  d  M%  [        U
S   S	9nU	R                  U5        MD     UR                  U	5        O9Ub6  [        U[        5      (       a!  U(       a  UnUR                  [        US	95        UR                  S/ 5      c  UR                  S5      b  UR                  [)        U5      5        UnUS-  nU[        U 5      :  a  X   S   S:X  a  GM[  U(       a  UR                  [!        SUS95        SS/nU[        U 5      :  a/  X   S   U;   a$  [+        X   U5      nUS-  nUR                  U5        U[        U 5      :  a4  X   S   U;  a)  [        U5      S:  a  UR                  [!        US95        / nXG:X  a  [-        SR/                  X   5      5      eU[        U 5      :  a  GM(  [        U5      S:  a  UR                  [!        US95        U$ ! [,         a  nUeSnAff = f)a  
Converts given messages from OpenAI format to Gemini format

- Parts must be iterable
- Roles must alternate b/w 'user' and 'model' (same as anthropic -> merge consecutive roles)
- Please ensure that function response turn comes immediately after a function call turn
usersystemNr   rolecontenttypetextrO   r&   rC   )r&   r*   FzNo text in user content. Adding a blank text to user content, to ensure Gemini doesn't fail the request. Relevant Issue - https://github.com/BerriAI/litellm/issues/5515 )rL   parts	assistant
tool_callsfunction_callmodeltoolfunctionrR   zWInvalid Message passed in - {}. File an issue https://github.com/BerriAI/litellm/issues )lenget
isinstancelistr	   r   r   appendr   dictrB   extendstrr"   r   warningContentTyper
   
model_dumpr   r   r   r5   r9   )rH   user_message_typescontentslast_message_with_tool_callsmsg_itool_call_responsesuser_content
init_msg_i_message_content_partselement_partimg_elementr&   has_text_in_contentassistant_contentmsg_dictassistant_msgassistant_texttool_call_message_rolesr@   s                        rA   %_gemini_convert_messages_with_historyrx   z   s    !(+"$H#' E{c(m#+-LJ H%(/&*AEW*W#+?#6#6y#A #/J?OQU4V4V-/F#3#FOv5 &' 1 #GFO 4q 8&*+CW&MG$,'&/$BE"MM%0$V_;&*+Dg&NG*1K)+k*BDII,7,DU,K	,7,D	$9I$NE"MM%0# $4$ !''/$0"#3S99,-1$*:;E ''.
A H%(/&*AEW*WD 
 '=\&J#&%/"** C !'' c* | LM "#h-'HOF,C{,Rhoy99LTOLfLfLhH'H > J J#0#4#4Y#E #/J?OQU4V4VF#3%gt44&v&8(0gfo(F &e 4	 $4
 &,,V4$0"#3S99(%5N%,,X>-JK "%%lB7C$((9E%,,:=I 4A0
C #h-'HOF,C{,RF !@Q RS (.z&:#H%OF+/FF:O%A 
#**51s8}$'/FF*+a/OOK6I$JK*,'"mtt  c c(m#l "#a'OOK.ABC s@   B9Q/ CQ/ C:Q/ Q/ CQ/ .CQ/ (Q/ /
R 9Q;;R rV   optional_paramscustom_llm_provider)	vertex_aivertex_ai_betageminilitellm_paramscached_contentc                 2   [        XS9n[        X`S9u  ppSU;   aK  [        XS9nUSL a=  [        XR	                  S5      S9n	U R                  SU	S.5        UR                  S5        / n
UR                  5        H@  u  pUR                  S5      (       d  M  UR                  X05        U
R                  U5        MB     UR                  5        VVs0 s H  u  pX;  d  M  X_M     nnn US	:X  a#  [        R                  " 5       R                  U S
9nO"[        R                  " 5       R                  U S
9nUR                  SS5      nUR                  SS5      nUR                  SS5      n[        R                  R!                  5       nUR                  5        VVs0 s H  u  pUU;   d  M  X_M     nnn[        S0 UD6n[#        US9nUb  UUS'   Ub  UUS'   Ub  UUS'   Ub  UUS'   Ub  UUS'   Ub  UUS'   U$ s  snnf s  snnf ! [$         a  nUeSnAff = f)zP
Common transformation logic across sync + async Gemini /generateContent calls.
)rV   rz   )supports_system_messagerH   response_schemaF)rV   r   rJ   )rL   rM   litellm_param_r}   )rH   toolsNtool_choicesafety_settings)rg   system_instruction
toolConfigsafetySettingsgenerationConfigcachedContentrZ   )r$   _transform_system_messager#   r   r\   r_   popitems
startswithupdatelitellmGoogleAIStudioGeminiConfig_transform_messagesVertexGeminiConfigr   __annotations__keysr   r5   )rH   rV   ry   rz   r~   r   r   system_instructionssupports_response_schemauser_response_schema_messageremove_keyskvrM   r   r   r   config_fieldsfiltered_paramsgeneration_configr/   r@   s                         rA   _transform_request_bodyr   	  s    : %> 7%! O+#?$
  $u,+A-@-@AR-S,( OOV8TUV 12 K%%'<<())!!1&)q! (
 )8(=(=(?X(?1CWtqt(?OX%(*88:NN! O G 002FF! G G "1!4!4Wd!C,;,?,?t,T?N?R?Rt@
 )88==? -224
4TQ]8JDAD4 	 
 9I 9
9
 G,*)<D%&!DM"!,D&%4D!"('8D#$%$2D! KS Y$
(  s>   G9G9(B2H G?*G?0AH ?H 
HHHgemini_api_keyapi_baseclienttimeoutextra_headerslogging_objc                     SSK Jn  U" 5       nU b*  UR                  UU UUUUUUR                  SS 5      US9	u  pOUR                  SS 5      n[	        UUU	U
UUS9$ Nr!   )ContextCachingEndpointsr   )	rH   api_keyr   rV   r   r   r   r   r   )rH   rV   rz   r~   r   ry   ))context_caching.vertex_ai_context_cachingr   check_and_create_cacher   r   r   rH   r   rV   r   r   r   ry   r   rz   r~   r   context_caching_endpointsr   s                 rA   sync_transform_request_bodyr   [  s     T 7 9!#<#S#S"'*../?F# $T 
$
 . ),,-=tD"/%%' rG   c                    #    SSK Jn  U" 5       nU b2  UR                  UU UUUUUUR                  SS 5      US9	I S h  vN u  pOUR                  SS 5      n[	        UUU	U
UUS9$  N'7fr   )r   r   async_check_and_create_cacher   r   r   s                 rA   async_transform_request_bodyr     s      T 7 9!+HH!&!+.223CTJ' I 
 
 	!. ),,-=tD"/%%' 
s   ;A'A%(A'r   c                 $   / n/ nU SL a  [        U5       H  u  pEUS   S:X  d  M  Sn[        US   [        5      (       a  [        US   S9nOK[        US   [        5      (       a3  SnUS    H  nXxR                  S5      =(       d    S-  nM!     [        US9nUc  M  UR                  U5        UR                  U5        M     [        U5      S	:  a#  [        U5       H  nUR                  U5        M     [        U5      S	:  a  [        US
9U4$ SU4$ )a=  
Extracts the system message from the openai message list.

Converts the system message to Gemini format

Returns
- system_content_blocks: Optional[SystemInstructions] - the system message list in Gemini format.
- messages: List[AllMessageValues] - filtered list of messages in OpenAI format (transformed separately)
TrL   rK   NrM   rP    rO   r   rY   )	enumerater]   rb   r   r^   r\   r_   r[   reversedr   r   )	r   rH   system_prompt_indicessystem_content_blocksidxmessage_system_content_blocksystem_textrM   s	            rA   r   r     s    ,.$&%h/LCv(*<@%gi0#66,4'):L,M)	 2D99"$K#*9#5#{{6':'@b@ $6,4+,F)(4)001FG)005 0 $%) 56S! 7  !A%!(=>HH>rG   )A__doc__r2   typingr   r   r   r   r   r   r	   httpxpydanticr
   r   litellm._loggingr   3litellm.litellm_core_utils.prompt_templates.factoryr   r   r   r   &litellm.llms.custom_httpx.http_handlerr   r   litellm.types.filesr   r   r   litellm.types.llms.openair   r   r   r   litellm.types.llms.vertex_air   r   r   r   r   r   r    common_utilsr"   r#   r$   *litellm.litellm_core_utils.litellm_loggingr%   _LiteLLMLoggingObjLiteLLMLoggingObjAnyrb   rB   r7   rd   rx   r`   r   floatTimeoutr   litellm_core_utilslitellm_loggingr   boolr   rZ   rG   rA   <module>r      s   
 M M M    +  Q 
  +    X*"S "X "Js x} 6L#$L	+L^O#$OO O !!HI	O
 O SMO Od'SM'#$' sm' 	'
 [!' eE5==012' D>' ' #' !!HI' ' 'T)SM)#$) sm) 	)
 %&) eE5==012) D>) ) ++;;CC) !!HI) ) )X$!$-12B-C$
8&'.>)??@$rG   