
    ggH                        d Z ddlZddlmZmZmZmZmZmZm	Z	 ddl
Z
ddlmZ ddlZddlmZ ddlmZmZmZmZ ddlmZmZ ddlmZmZmZ dd	lmZmZmZm Z  dd
l! ddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( ddl)m*Z*m+Z+m,Z, er	ddl-m.Z/ e/Z0ne1Z0de2de#fdZ3de2dee2   fdZ4dee   dee5   fdZ6dee   de2de7ded   de7dee2   de$fdZ8dee2   dee   dee2   de2dee   d eee9e
jt                  f      d!ee7   de7d"e0ded   de7de$fd#Z;dee2   dee   dee2   de2dee   d eee9e
jt                  f      d!ee7   de7d"ejx                  jz                  j\                  ded   de7de$fd$Z>d%e?dee   deee&   ee   f   fd&Z@y)'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                    	 d| v rot         j                  j                  |       d   }|dd }t        |      }t	        |      st        d|       t        |      }t        ||       }t        |      S d| v r&t        |       x}t        | |	      }t        |      S d
| v sd| v sd| v r*t        |       }t        |d   |d         }t        |      S t        dj                  |             # t
        $ r}	|	d}	~	ww xY w)zH
    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+   zhttp://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
             a/var/www/openai/venv/lib/python3.12/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$y9MIi00)#<YGGT$i:NIi00)#zY'>(iBW29=E%-5;NOE..5<<YGHH s*   A2C/ 5)C/ 5C/ C/ /	C?8C::C?urlc                     | j                         } | j                  d      ry| j                  d      ry| j                  d      ry| j                  d      ry| j                  d	      ry
y)an  
    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   _   s^     ))+C
||%&	f		g		f		f	     messagesc                    ddh}g }d}d}g }	 |t        |       k  rg }|}|t        |       k  rO| |   d   |v rD| |   j                  d      }|t        |t              rg }	|D ]  }
|
d   dk(  rFd|
v rBt        |
d         dkD  r1t	        t
        |
      }
t        |
d   	      }|	j                  |       Q|
d   d
k(  sZt	        t        |
      }
|
}t        |d
   t              r	|d
   d   }n|d
   }t        |      }|	j                  |        |j                  |	       n=|;t        |t              r+t        |      dkD  rt        |	      }|j                  |       |dz  }|t        |       k  r| |   d   |v rD|r\	 t        |      }|du r0t        j                  d       |j                  t        d	             |j                  t!        d|             g }|t        |       k  rL| |   d   dk(  r@t        | |   t"              r| |   j%                         }n| |   }t'        di |}|j                  dd      }|et        |t              rUg }	|D ]<  }
t        |
t              s|
d   dk(  st        |
d   	      }|	j                  |       > |j                  |	       n1|/t        |t              r|r|}|j                  t        |	             |j                  dg       |j                  d      |j                  t)        |             |}|dz  }|t        |       k  r| |   d   dk(  r@|r|j                  t!        d|             ddg}|t        |       k  r/| |   d   |v r%t+        | |   |      }|dz  }|j                  |       |t        |       k  r5| |   d   |vr+t        |      dkD  r|j                  t!        |             g }||k(  rt-        dj/                  | |               |t        |       k  rt        |      dkD  r|j                  t!        |             |S # t,        $ r}|d}~ww xY w)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%(5/&*AEW*W#+E?#6#6y#A #/J?OQU4V-/F#3#FOv5 &' 1 #GFO 4q 8&*+CW&MG$,'&/$BE"MM%0$V_;&*+Dg&NG*1K)+k*BDI,7,DU,K	,7,D	$9I$NE"MM%0# $4$ !''/$0"#3S9,-1$*:;E ''.
A H%(5/&*AEW*WD 
 '=\&J#&%/"** C !'' c* | LM "#h-'HUOF,C{,Rhuoy9LTUZOLfLfLhH'H > J J#0#4#4Y#E #/J?OQU4VF#3%gt4&v&8(0gfo(F &e 4	 $4
 &,,V4$0"#3S9(%5N%,,X>-JK "%%lB7C$((9E%,,:=I 4A0
C #h-'HUOF,C{,RF !@Q RS (.z&:#H%UOF+/FF:UO%A 
#**51s8}$'/FF*+a/OOK6I$JK*,'
"mtt  c c(m#l "#a'OOK.ABC s@   B0P9 ?B>P9 ?C-P9 -P9 6CP9 :CP9 *P9 9	Q	QQ	rV   optional_paramscustom_llm_provider)	vertex_aivertex_ai_betageminilitellm_paramscached_contentc                 2   t        ||      }t        ||       \  }} d|v rRt        ||      }|du rAt        ||j	                  d            }	| j                  d|	d       |j                  d       g }
|j                         D ];  \  }}|j                  d      s|j                  ||i       |
j                  |       = |j                         D ci c]  \  }}||
vs|| }}}	 |d	k(  r%t        j                         j                  | 
      }n$t        j                         j                  | 
      }|j                  dd      }|j                  dd      }|j                  dd      }t        j                  j!                         }|j                         D ci c]  \  }}||v s|| }}}t        di |}t#        |      }|||d<   |||d<   |||d<   |||d<   |||d<   |||d<   |S c c}}w c c}}w # t$        $ r}|d}~ww xY w)zX
    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<<()!!1a&)q! (
 )8(=(=(?X(?11KCWq!t(?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]8JAqD4 	 
 9I 9
9
 G,*)<D%&!DM"!,D&%4D!"('8D#$%$2D! KS Y$
(  s>   G:$G:-B5H "H /H 4AH  H 	HHHgemini_api_keyapi_baseclienttimeoutextra_headerslogging_objc                     ddl m}  |       }| .|j                  || ||||||j                  dd       |	      \  }}n|j                  dd       }t	        |||	|
||      S 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                    K   ddl m}  |       }| 6|j                  || ||||||j                  dd       |	       d {   \  }}n|j                  dd       }t	        |||	|
||      S 7 +w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                    g }g }| du rt        |      D ]  \  }}|d   dk(  sd}t        |d   t              rt        |d         }nCt        |d   t              r0d}|d   D ]  }||j                  d      xs dz  } t        |      }|z|j                  |       |j                  |        t        |      d	kD  r!t        |      D ]  }|j                  |        t        |      d	kD  rt        |
      |fS d|fS )aU  
    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,4'):L,M)	 2D9"$K#*9#5#w{{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   