
    hP                        d dl Z d dlmZmZmZmZmZmZmZm	Z	m
Z
 d dlZd dlZd dl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mZ  G d d	e      Zd
eded   defdZd
eded   defdZd dlmZmZ ed   Zded
edee   dee   dee   ded   deeef   fdZded
edee   dee   deeef   f
dZ dee   defdZ!d6de"defdZ#d eeef   deeef   fd!Z$d7d"Z%	 d7d#eeef   d$e&deeef   fd%Z'	 d8d eeef   d&ee   deeef   fd'Z(d7d(Z)d) Z*d*efd+Z+d,ede&fd-Z,d.edee   fd/Z-d.edee   fd0Z.d1edededefd2Z/d3ed1edee   dee   dej`                  f
d4Z1d
edefd5Z2y)9    N)	AnyDictListLiteralOptionalSetTupleUnionget_type_hints)supports_response_schemasupports_system_messagesverbose_logger)DEFAULT_MAX_RECURSE_DEPTH)unpack_defs)BaseLLMException)PartTypeSchemac            
       T     e Zd Z	 ddededeeeej                  f      f fdZ
 xZS )VertexAIErrorstatus_codemessageheadersc                 *    t         |   |||       y )N)r   r   r   )super__init__)selfr   r   r   	__class__s       _/var/www/Befach/backend/env/lib/python3.12/site-packages/litellm/llms/vertex_ai/common_utils.pyr   zVertexAIError.__init__   s     	k7S    N)__name__
__module____qualname__intstrr   r
   r   httpxHeadersr   __classcell__)r   s   @r   r   r      sF    
 9=	TT T %emm 345	T Tr   r   modelcustom_llm_provider)	vertex_aivertex_ai_betageminireturnc                    	 |}|dk(  rd}t        | |      }t        j                  j                  |       rd}|S # t        $ r:}t        j                  dj                  t        |                   d}Y d }~|S d }~ww xY w)Nr,   r+   r)   r*   TzUnable to identify if system message supported. Defaulting to 'False'. Received error message - {}
Add it here - https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.jsonF)	r   litellmVertexGeminiConfig_is_model_gemini_spec_model	Exceptionr   warningformatr%   )r)   r*   _custom_llm_providersupports_system_messagees        r   get_supports_system_messager:      s    (2"22#. ":-A#

 %%AA%H&*# #"  ( R  Y  YA	

 #(""(s   7; 	A>/A99A>c                 2    |}|dk(  rd}t        | |      }|S )Nr,   r+   r0   )r   )r)   r*   r7   _supports_response_schemas       r   get_supports_response_schemar=   1   s2     /..* 8)=! %$r   )r   r   )chat	embeddingbatch_embeddingimage_generationmodestreamvertex_projectvertex_locationvertex_api_version)v1v1beta1c                    d }d }t         j                  j                  |      }| dk(  rd}|du r-d}|dk(  rd| d| d	| d
| d	}n>d| d| d| d| d| d
| d}n(|dk(  rd| d| d	| d
| }nd| d| d| d| d| d
| }|j                         rd| d| d| d| d| d
| }|du r|dz  }ny| dk(  r8d}d| d| d| d| d
| 
}|j                         rQd| d| d| d| d| d
| }n<| dk(  r7d}d| d| d| d| d
| 
}|j                         rd| d| d| d| d| d
| }|r|st	        d|        ||fS )N)r)   r>   generateContentTstreamGenerateContentglobalz"https://aiplatform.googleapis.com/
/projects/z+/locations/global/publishers/google/models/:z?alt=ssezhttps://z-aiplatform.googleapis.com//locations/z/publishers/google/models/z/endpoints/r?   predictz'-aiplatform.googleapis.com/v1/projects/rA   z,Unable to get vertex url/endpoint for mode: )r1   r2   get_model_for_vertex_ai_urlisdigit
ValueError)rB   r)   rC   rD   rE   rF   urlendpoints           r   _get_vertex_urlrV   F   s    C"H&&BBBOEv~$T>.H(*:;M:NjYgXh  iT  UZ  T[  [\  ]e  \f  fn  o  11LM_L``jkyjz  {F  GV  FW  Wq  rw  qx  xy  zB  yC  CK  L(*:;M:NjYgXh  iT  UZ  T[  [\  ]e  \f  g  11LM_L``jkyjz  {F  GV  FW  Wq  rw  qx  xy  zB  yC  D
 ==?_--HI[H\\fgufv  wB  CR  BS  S^  _d  ^e  ef  go  fp  qC~z!		))PQ_P``kl{k|  }W  X]  W^  ^_  `h  _i  j==?_--HI[H\\fgufv  wB  CR  BS  S^  _d  ^e  ef  go  fp  qC	#	#))PQ_P``kl{k|  }W  X]  W^  ^_  `h  _i  j==?_--HI[H\\fgufv  wB  CR  BS  S^  _d  ^e  ef  go  fp  qChGvNOO=r   gemini_api_keyc                 :   dj                  |      }| dk(  r6d}|du rd}dj                  |||      }||fS dj                  |||      }||fS | dk(  rd	}dj                  |||      }||fS | d
k(  rd}dj                  |||      }||fS | dk(  rt        d      fS )Nz	models/{}r>   rJ   TrK   zEhttps://generativelanguage.googleapis.com/v1beta/{}:{}?key={}&alt=ssez=https://generativelanguage.googleapis.com/v1beta/{}:{}?key={}r?   embedContentr@   batchEmbedContentsrA   zLiteLLM's `gemini/` route does not support image generation yet. Let us know if you need this feature by opening an issue at https://github.com/BerriAI/litellm/issues)r6   rS   )rB   r)   rC   rW   _gemini_model_namerU   rT   s          r   _get_gemini_urlr\   y   s    %++E2v~$T>.HY``"HnC0 =' PVV&. ( = 
	!MTT.
 = 
"	"'MTT.
 = 
#	# u
 	
 =r   partsc                 J    d}| D ]  }d|v s|j                  d      sd} |S )a	  
    check that user_content has 'text' parameter.
        - Known Vertex Error: Unable to submit request because it must have a text parameter.
        - 'text' param needs to be len > 0
        - Relevant Issue: https://github.com/BerriAI/litellm/issues/5515
    FtextT)get)r]   has_text_paramparts      r   _check_text_in_contentrc      s2     NT>dhhv.!N  r   
parametersadd_property_orderingc                 J   t        t        t              j                               }| j	                  di       }|j                         D ]  \  }}t        ||        t        | |       t        |        t        |        t        |        t        | |      } |rt        |        | S )a  
    This is a modified version of https://github.com/google-gemini/generative-ai-python/blob/8f77cc6ac99937cd3a81299ecf79608b91b06bbb/google/generativeai/types/content_types.py#L419

    Updates the input parameters, removing extraneous fields, adjusting types, unwinding $defs, and adding propertyOrdering if specified, returning the updated parameters.

    Parameters:
        parameters: dict - the json schema to build from
        add_property_ordering: bool - whether to add propertyOrdering to the schema. This is only applicable to schemas for structured outputs. See
          set_schema_property_ordering for more details.
    Returns:
        parameters: dict - the input parameters, modified in place
    z$defs)setr   r   keyspopitemsr   convert_anyof_null_to_nullableprocess_itemsadd_object_typefilter_schema_fieldsset_schema_property_ordering)rd   re   valid_schema_fieldsdefsnamevalues         r   _build_vertex_schemart      s     nV499;<>>'2&Dzz|eE4  $
D! #:. *J &j2EFJ$Z0r   schema_dictc                    | j                  dd      }| j                  dd      }t        | t              rX| j                  d      rG| d   }|s|r<t        |t              r,t	        d |D              r|D ]  }|r||d<   |s||d<    d|iS | S | S )aM  
    When anyof is present, only keep the anyof field and its contents - otherwise VertexAI will throw an error - https://github.com/BerriAI/litellm/issues/11164
    Filter out other fields in the same dict.

    E.g. {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "test"} -> {"anyOf": [{"type": "string"}, {"type": "null"}]}

    Case 2: If additional metadata is present, try to keep it
    E.g. {"anyOf": [{"type": "string"}, {"type": "null"}], "default": "test", "title": "test"} -> {"anyOf": [{"type": "string", "title": "test"}, {"type": "null", "title": "test"}]}
    titleNdescriptionanyOfc              3   <   K   | ]  }t        |t                y wr    )
isinstancedict).0items     r   	<genexpr>z'_filter_anyof_fields.<locals>.<genexpr>   s     >tJtT*>s   )r`   r{   r|   listall)ru   rw   rx   any_ofr~   s        r   _filter_anyof_fieldsr      s     OOGT*E//-6K+t$)AW%k64(>v>>$)DM*5D'	 
 V$$r   c                 d   |t         kD  rt        dt          d      t        | t              rd| v r| d   i k(  rddi| d<   | j	                         D ]]  \  }}t        |t              rt        ||dz          &t        |t              s7|D ]"  }t        |t              st        ||dz          $ _ y y )NMax depth of Q exceeded while processing schema. Please check the schema for excessive nesting.rj   typeobject   )r   rS   r{   r|   rj   rl   r   )schemadepthkeyrs   r~   s        r   rl   rl      s    ((56  7H  I
 	
 &$fB!6%x0F7O ,,.JC%&eUQY/E4(!D!$-%dEAI6 "	 )  r   r   r   c                 R   |t         kD  rt        dt          d      d| v rjt        | d   t              rWd| vr)| d   j	                         D cg c]  \  }}|	 c}}| d<   | d   j	                         D ]  \  }}t        ||dz           d| v rt        | d   |dz          | S c c}}w )ay  
    vertex ai and generativeai apis order output of fields alphabetically, unless you specify the order.
    python dicts retain order, so we just use that. Note that this field only applies to structured outputs, and not tools.
    Function tools are not afflicted by the same alphabetical ordering issue, (the order of keys returned seems to be arbitrary, up to the model)
    https://cloud.google.com/vertex-ai/docs/reference/rest/v1/projects.locations.cachedContents#Schema.FIELDS.property_ordering

    Args:
        schema: The schema dictionary to process
        depth: Current recursion depth to prevent infinite loops
    r   r   
propertiespropertyOrderingr   rj   )r   rS   r{   r|   rj   ro   )r   r   kvs       r   ro   ro     s     ((56  7H  I
 	
 v*VL-A4"HV+8>|8L8R8R8T)U1!)UF%&<(..0DAq(EAI6 1&$VG_eai@M *Vs   B#valid_fieldsc                 ^   |
t               }t        |       }||v r| S |j                  |       t        | t              s| S i }t        |       } | j                         D ]  \  }}||vr|dk(  rCt        |t              r3|j                         D ci c]  \  }}|t        |||       c}}||<   S|dk(  r|dv r|||<   bc|dk(  r!t        |t              rt        |||      ||<   |dk(  r/t        |t              r|D 	cg c]  }	t        |	||       c}	||<   |||<    |S c c}}w c c}	w )zK
    Recursively filter a schema dictionary to keep only valid fields.
    r   r6   >   	date-timeenumrj   ry   )	rg   idaddr{   r|   r   rj   rn   r   )
ru   r   	processed	schema_idresultr   rs   r   r   r~   s
             r   rn   rn   %  sN    E	 ;IIMM)k4(F&{3K!'')
Ul",:eT#: "KKMAq '<CCF3K H_--#sG^
5$ 7.ulINF3KG^
5$ 7PUHL$T<CF3K  F3K+ *. M%s   D$ D*c                 L   |t         kD  rt        dt          d      	 | j                  dd       }|d}|D ]6  }|ddik(  r|j                  |       d}d|vs#t	        |      dk(  s2d	|d<   8 t	        |      dk(  rt        d
      |r:|D ]5  }|j                  d      dk(  rd|v r|d   s|j                  d       d|d<   7 | j                  dd       }|(|j                         D ]  \  }}t        ||dz           | j                  dd       }|t        ||dz          y y )Nr   r   ry   Fr   nullTr   r   zaInvalid input: AnyOf schema with only null type is not supported. Please provide a non-null type.arrayrj   nullabler   r   )r   )r   rS   r`   removelenri   rj   rk   )	r   r   anyofcontains_nullatyper   rr   rs   rj   s	            r   rk   rk   S  s_   ((56  7H  I
 	
 mJJw%EE((U# $u$Uq (f  u:?2 
  IIf%05(!'NIIg&$(j!  L$/J%++-KD%*5	B . JJw%E&uEAI> r   c                     | j                  dd       }|Cd| v r| d   | j                  dd        d| d<   |j                         D ]  \  }}t        |        | j                  dd       }|t        |       y y )Nr   requiredr   r   rj   )r`   ri   rj   rm   )r   r   rr   rs   rj   s        r   rm   rm     s    L$/JF:$6$>JJz4(!v%++-KD%E" . JJw%E r   
field_namec                     | j                  |d        | j                  dd       }|$|j                         D ]  \  }}t        ||        | j                  dd       }|t        ||       y y )Nr   rj   )ri   r`   rj   strip_field)r   r   r   rr   rs   rj   s         r   r   r     sn    
JJz4 L$/J%++-KD%z* . JJw%EE:& r   vertex_datetimec                 d    ddl m } |j                  | d      }t        |j                               S )z
    Converts a Vertex AI datetime string to an OpenAI datetime integer

    vertex_datetime: str = "2024-12-04T21:53:12.120184Z"
    returns: int = 1722729192
    r   )datetimez%Y-%m-%dT%H:%M:%S.%fZ)r   strptimer$   	timestamp)r   r   dts      r   +_convert_vertex_datetime_to_openai_datetimer     s-     " 
		?,C	DBr||~r   rT   c                 X    t        j                  d|       }|r|j                  d      S dS )z
    Get the vertex project id from the url

    `https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:streamGenerateContent`
    z/projects/([^/]+)r   NresearchgrouprT   matchs     r   get_vertex_project_id_from_urlr     s*     II*C0E"5;;q>,,r   c                 X    t        j                  d|       }|r|j                  d      S dS )z
    Get the vertex location from the url

    `https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:streamGenerateContent`
    z/locations/([^/]+)r   Nr   r   s     r   get_vertex_location_from_urlr     s*     II+S1E"5;;q>,,r   requested_routec                 B    t        j                  dd| d| d|       }|S )zS
    Replace project and location values in the route with the provided values
    z /projects/[^/]+/locations/[^/]+/rM   rO   /)r   sub)r   rD   rE   modified_routes       r   %replace_project_and_location_in_router     s4     VV+
^$K/@BN
 r   base_urlc                     t        j                  |       }d|v r#|r|rt        |||      }|j                  |      S 	 d}d|v rd}dj	                  |||      }d|z   |z   }|j                  |      }|S )a<  
    Allow user to specify their own project id / location.

    If missing, use defaults

    Handle cachedContent scenario - https://github.com/BerriAI/litellm/issues/5460

    Constructed Url:
    POST https://LOCATION-aiplatform.googleapis.com/{version}/projects/PROJECT_ID/locations/LOCATION/cachedContents
    	locations)pathrG   cachedContentrH   z{}/projects/{}/locations/{}r   )r&   URLr   	copy_withr6   )	r   r   rE   rD   new_base_urlvertex_versionbase_requested_routeupdated_requested_routeupdated_urls	            r   construct_target_urlr     s    " 99X&Lo%oCO %%?%;;
 04N/)"8?? "$88?J((.E(FKr   c                 0    ddl m}  || d      }|yd|v S )z
    Check if a model is only available in the global region.

    Args:
        model: The model name to check

    Returns:
        True if the model is only available in global region, False otherwise
    r   )get_supported_regionsr+   r0   FrL   )litellm.utilsr   )r)   r   supported_regionss      r   is_global_only_vertex_modelr     s.     4-  (((r   )F)r   r    )3r   typingr   r   r   r   r   r   r	   r
   r   r&   r1   r   r   r   litellm.constantsr   8litellm.litellm_core_utils.prompt_templates.common_utilsr   )litellm.llms.base_llm.chat.transformationr   litellm.types.llms.vertex_air   r   r   r%   boolr:   r=   all_gemini_url_modesrV   r\   rc   r|   rt   r   rl   r$   ro   rn   rk   rm   r   r   r   r   r   r   r   r    r   r   <module>r      s   	 X X X   V V 7 P F 9T$ T##%,-T%U#	#2%%%,-T%U%	% %> 
0
00 TN0 SM	0
 c]0  00 38_0f#
## TN# SM	#
 38_#L$x. T 'T '$ 'Td38n c3h >7$ *+cN#&	#s(^< DH+c3h+/23x+	#s(^+\,?^
'C 
'  - - --c -hsm -*-@C))) c]) SM	)
 YY)X)s )t )r   