
    i{                         d Z ddlZddlZddlmZmZmZmZmZm	Z	 ddl
Z
ddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZ d	d
lmZmZmZmZmZ dZerddlmZ neZ G d d      Z y)z
Base Vertex, Google AI Studio LLM Class

Handles Authentication and generating request urls for Vertex AI and Google AI Studio
    N)TYPE_CHECKINGAnyDictLiteralOptionalTuple)verbose_logger)asyncify)AsyncHTTPHandler)get_secret_str)VERTEX_CREDENTIALS_TYPESVertexPartnerProvider   )_get_gemini_url_get_vertex_urlall_gemini_url_modesget_vertex_base_model_nameget_vertex_base_urlzqGoogle Cloud SDK not found. Install it with: pip install 'litellm[google]' or pip install google-cloud-aiplatform)Credentialsc                       e Zd Zd: fdZdee   dedefdZdee   dee   dee	ef   fd	Z
d
 Zd Zd Zd Zd ZdefdZdee   dee   defdZe	 d;dedededee   dedee   defd       Zdee   dee   dee   dededee   dedefdZde	ddfdZdee   dee   ded   deeef   fdZdedefdZ	 	 	 	 	 d<dee   dedee   d edee   d!ee   d"edee   dee   dee   d#eed$      d%edeee   ef   fd&Z	 	 	 d=ded!ee   dee   dee   dee   d'ee   dee   ded   dee   d(ee   d)ed%edeee   ef   fd*Zdee   dee   d+ed,edeeef   f
d-Z 	 d>dee   dee   d.edeeef   fd/Z!dee   dee   ded   deeef   fd0Z"d!ee   d1ee   defd2Z#ed3edee   fd4       Z$ed3edee   fd5       Z%ed3edee   fd6       Z&ed3edee   fd7       Z'ed3edee   fd8       Z(ed3edee   fd9       Z) xZ*S )?
VertexBasereturnNc                 v    t         |           d | _        d | _        d | _        i | _        d | _        d | _        y N)super__init__access_tokenrefresh_token_credentials_credentials_project_mapping
project_idasync_handler)self	__class__s    w/Users/manta/Documents/Projects/TheRoad-I1/.venv/lib/python3.12/site-packages/litellm/llms/vertex_ai/vertex_llm_base.pyr   zVertexBase.__init__&   sD    +/,0?C  	) *.9=    vertex_regionmodelc                    dd l }|j                  d      sd| n|}|j                  j                  |i       }|j                  d      }|r<t	        |      dkD  r.||d   S ||vr!t        j                  d||||d          |d   S |S |xs dS )Nr   z
vertex_ai/supported_regionszSVertex AI model '%s' does not support region '%s' (supported: %s). Routing to '%s'.us-central1)litellm
startswith
model_costgetlenr	   warning)r#   r'   r(   r,   	model_key
model_infor*   s          r%   get_vertex_regionzVertexBase.get_vertex_region2   s    
 ).(8(8(Fj E 	 ''++Ir:
&NN+>?%6!7!!;$(++$55&&8!%%a( )++  --r&   credentialsr!   c                    |t        |t              rt        j                  d|       t        j                  d|t        j
                  j                  |      t	        j                                	 t        j
                  j                  |      rt        j                  t        |            }nt        j                  |      }n6t        |t              r|}n#t        dj                  t!        |                  d|v r|d   dk(  r|j#                  di       }t        |t              r|j#                  dd	      nd	}t        |t              rHd
|v rDddlm} |j)                  |      }|r|j+                  ||dg      }nm| j-                  |dg      }nX| j/                  |dg      }nCd|v r+|d   dk(  r#| j1                  |dg      }|!|j2                  }n| j5                  |dg      }|(t7        |dd       }n| j9                  dg      \  }}	||	}| j;                  |       |st        d      t        |t              st=        dt!        |             ||fS # t        $ r t        dj                  |            w xY w)Nz*Vertex: Loading vertex credentials from %szVVertex: checking if credentials is a valid path, os.path.exists(%s)=%s, current dir %sz:Unable to load vertex credentials from environment. Got={}zInvalid credentials type: {}typeexternal_accountcredential_sourceenvironment_id awsr   )VertexAIAwsWifAuthz.https://www.googleapis.com/auth/cloud-platform)
aws_paramsscopesr?   authorized_userr!   Could not resolve project_idz(Expected project_id to be a str but got )
isinstancestrr	   debugospathexistsgetcwdjsonloadopenloads	Exceptionformatdict
ValueErrorr7   r/   (litellm.llms.vertex_ai.vertex_ai_aws_wifr=   extract_aws_paramscredentials_from_explicit_aws(_credentials_from_identity_pool_with_aws_credentials_from_identity_pool!_credentials_from_authorized_userquota_project_id!_credentials_from_service_accountgetattr_credentials_from_default_authrefresh_auth	TypeError)
r#   r5   r!   json_objr9   r:   r=   r>   credscreds_project_ids
             r%   	load_authzVertexBase.load_authO   s    "+s+$$@+ $$lGGNN;/IIK	
ww~~k2#'99T+->#?#'::k#: K.& 299${:KL 
 !hv&6:L&L$,LL1Db$I! ""3T: &))*:B? 
 nc2u7N "4!F!Fx!PJ! 2 P P$'1$T#U !Q ! !% M M$$T#U !N !
 !@@  PQ A E
 8#(8<M(M>>LM ?  %..  >>LM ? 
 !$UL$?
&*&I&IHI 'J '#E# !-
% ;<<*c*:4
;K:LM  j  a ! #T[[' s   2AI! !$Jc                     	 ddl m} |j                  j                  |      }|r)t        |d      r|j                  r|j                  |      }|S # t        $ r t        t              w xY w)Nr   )identity_poolrequires_scopes)	google.authrc   ImportErrorGOOGLE_IMPORT_ERROR_MESSAGEr   	from_infohasattrrd   with_scopes)r#   r^   r?   rc   r_   s        r%   rV   z*VertexBase._credentials_from_identity_pool   si    	;1 ))33H=ge%67E<Q<Q%%f-E  	;9::	;   A A)c                     	 ddl m} |j                  j                  |      }|r)t        |d      r|j                  r|j                  |      }|S # t        $ r t        t              w xY w)Nr   )r<   rd   )	re   r<   rf   rg   r   rh   ri   rd   rj   )r#   r^   r?   r<   r_   s        r%   rU   z3VertexBase._credentials_from_identity_pool_with_aws   sg    	;' ))(3ge%67E<Q<Q%%f-E  	;9::	;rk   c                     	 dd l }|j                  j                  j
                  j                  ||      S # t        $ r t        t              w xY wNr   r@   )google.oauth2.credentialsrf   rg   oauth2r5   r   from_authorized_user_infor#   r^   r?   googles       r%   rW   z,VertexBase._credentials_from_authorized_user   sW    	;, }}((44NNV O 
 	
  	;9::	;	   7 Ac                     	 dd l }|j                  j                  j
                  j                  ||      S # t        $ r t        t              w xY wrn   )google.oauth2.service_accountrf   rg   rp   service_accountr   from_service_account_inforr   s       r%   rY   z,VertexBase._credentials_from_service_account   sW    	;0 }},,88RRV S 
 	
  	;9::	;rt   c                 l    	 dd l m} |j	                  |      S # t        $ r t        t              w xY wrn   )re   authrf   rg   default)r#   r?   google_auths      r%   r[   z)VertexBase._credentials_from_default_auth   s=    	;- ""&"11  	;9::	;s    3c                      y)Nr+    )r#   s    r%   get_default_vertex_locationz&VertexBase.get_default_vertex_location   s    r&   api_basevertex_locationc                 D    |r|S t        |xs | j                               S r   )r   r   )r#   r   r   s      r%   get_api_basezVertexBase.get_api_base   s*     O"At??A
 	
r&   vertex_projectpartnerstreamc                    |t        |       }|t        j                  k(  r| d| d|  dS |t        j                  k(  r|r| d| d|  d| dS | d| d|  d| dS |t        j                  k(  r|r| d| d|  d	| dS | d| d|  d	| dS |t        j
                  k(  r|r| d| d|  d
| dS | d| d|  d
| dS y)z1Return the base url for the vertex partner modelsNz/v1/projects/z/locations/z#/endpoints/openapi/chat/completionsz/publishers/mistralai/models/z:streamRawPredictz:rawPredictz/v1beta1/projects/z/publishers/ai21/models/z/publishers/anthropic/models/)r   r   llama	mistralaiai21clauder   r   r   r   r(   r   s         r%   create_vertex_urlzVertexBase.create_vertex_url   s    *?;H+111Z}^,<KGXX{||-777"=0@OK\\yz  zA  AR  S  S"=0@OK\\yz  zA  AL  M  M-222"#5n5E[Q`Paayz  zA  AR  S  S"#5n5E[Q`Paayz  zA  AL  M  M-444"=0@OK\\yz  zA  AR  S  S"=0@OK\\yz  zA  AL  M  M	 5r&   custom_api_basec                 <   | j                  ||      }| j                  ||      }	t        j                  ||xs |||||	      }
t	        |
j                  d            dkD  r|
j                  d      d   }nd}| j                  |dd ||d |
||xs ||d	      \  }}	|	S )
N)r   r   r   :r   r;   	vertex_aiv1)r   custom_llm_providergemini_api_keyendpointr   auth_headerurlr(   r   r   vertex_api_version)r4   r   r   r   r0   split_check_custom_proxy)r#   r   r   r   r!   r   r   r(   resolved_locationr   default_api_baser   _s                r%   get_complete_vertex_urlz"VertexBase.get_complete_vertex_url  s     !22?EJ$$$6G % 
 &77-)7Z 8 
 %%c*+a/'--c226HH..$ + )7Z-# / 
8 r&   c                 v    	 ddl m} |j	                   |              y # t        $ r t        t              w xY w)Nr   )Request)google.auth.transport.requestsr   rf   rg   refresh)r#   r5   r   s      r%   r\   zVertexBase.refresh_auth?  s;    	; 	GI&  	;9::	;s    8r   )r   vertex_ai_betageminic                 4    |dk(  ry| j                  ||      S )z3
        Returns auth token and project id
        r   r;   r;   r5   r!   )get_access_token)r#   r5   r!   r   s       r%   _ensure_access_tokenzVertexBase._ensure_access_tokenI  s-     (*(('% )  r&   optional_paramsc                      y)z
        use this helper to decide if request should be sent to v1 or v1beta1

        Returns true if any beta feature is enabled
        Returns false in all other cases
        Fr~   )r#   r   s     r%   is_using_v1beta1_featuresz$VertexBase.is_using_v1beta1_features\  s     r&   r   r   r   r   r   )r   v1beta1use_psc_endpoint_formatc                 L   |r|dk(  r4|t        d      dj                  |||      }|t        d      |bd|i}n]|rI|	r|
r|st        d      t        |      }|xs d}d	j                  |j                  d
      ||	|
||      }ndj                  ||      }|du r|dz   }||fS )a  
        for cloudflare ai gateway - https://github.com/BerriAI/litellm/issues/4317

        Handles custom api_base for:
        1. Gemini (Google AI Studio) - constructs /models/{model}:{endpoint}
        2. Vertex AI with standard proxies - constructs {api_base}:{endpoint}
        3. Vertex AI with PSC endpoints - constructs full path structure
           {api_base}/v1/projects/{project}/locations/{location}/endpoints/{model}:{endpoint}
           (only when use_psc_endpoint_format=True)

        Args:
            use_psc_endpoint_format: If True, constructs PSC endpoint URL format.
                                     If False (default), uses api_base as-is and appends :{endpoint}

        ## Returns
        - (auth_header, url) - Tuple[Optional[str], str]
        r   z;Model parameter is required for Gemini custom API base URLsz{}/models/{}:{}z3Missing gemini_api_key, please set `GEMINI_API_KEY`zx-goog-api-keyzYvertex_project, vertex_location, and model are required when use_psc_endpoint_format=True)r(   r   z.{}/{}/projects/{}/locations/{}/endpoints/{}:{}/z{}:{}Tz?alt=sse)rQ   rO   r   rstrip)r#   r   r   r   r   r   r   r   r(   r   r   r   r   model_for_urlversions                  r%   r   zVertexBase._check_custom_proxye  s    @ "h.=$U  (..xI!)$M  "-#3^"DK + +5(w  %?U$KM08DGJQQ ,&'% C "..8<C~J&Cr&   vertex_credentialsshould_use_v1beta1_featuresmodec                     d}|dk(  rt        ||||      \  }}d}n/| j                  ||      }|
du rdnd}t        ||||||      \  }}| j                  |	|||||||||||	      S )
z
        Internal function. Returns the token and url for the call.

        Handles logic if it's google ai studio vs. vertex ai.

        Returns
            token, url
        Nr   )r   r(   r   r   )r'   r(   Tr   r   )r   r(   r   r   r   r   )r   r   r   r   r   r   r   r(   r   r   r   r   )r   r4   r   r   )r#   r(   r   r   r   r   r   r   r   r   r   r   r   r   r   r   s                   r%   _get_token_and_urlzVertexBase._get_token_and_url  s    . 7;(*+-	MC K"44- 5 O $?$#FiDG+- /#*MC ''# 3))+&$; ( 
 	
r&   credential_cache_keyerrorc                    t        j                  d| d       || j                  v r| j                  |= 	 | j                  ||d      S # t        $ r7}t        j
                  d| dt        |       dt        |              |d}~ww xY w)	ab  
        Handle reauthentication when credentials refresh fails.

        This method clears the cached credentials and attempts to reload them once.
        It should only be called when "Reauthentication is needed" error occurs.

        Args:
            credentials: The original credentials
            project_id: The project ID
            credential_cache_key: The cache key to clear
            error: The original error that triggered reauthentication

        Returns:
            Tuple of (access_token, project_id)

        Raises:
            The original error if reauthentication fails
        z*Handling reauthentication for project_id: z#. Clearing cache and retrying once.T)r5   r!   _retry_reauthz.Reauthentication retry failed for project_id: z. Original error: z. Retry error: N)r	   rE   r    r   rN   r   rD   )r#   r5   r!   r   r   retry_errors         r%   _handle_reauthenticationz#VertexBase._handle_reauthentication  s    2 	8 E0 1	
  4#D#DD112FG	(('%" )  
  	  @ M##&u:,oc+>N=OQ
 K	s   A
 
	B
2BB
r   c                 f   t        |t              rt        j                  |      n|}||f}d}t	        j
                  d|        || j                  v rt	        j
                  d| d       | j                  |   }t	        j
                  d|       t        |t              r|\  }}n|}|j                  xs t        |dd      }t	        j
                  d|       n]t	        j
                  d| d	       	 | j                  ||
      \  }}|t        dj                  |            ||f| j                  |<   t	        j
                  d|        |7|5t        |t              r%|}||f}
|
| j                  vr||f| j                  |
<   |t        d      |j                   r;	 t	        j
                  d|        | j#                  |       ||f| j                  |<   |j&                  t        |j&                  t              s$t        dj                  |j&                              |t        d      |j&                  |fS # t        $ r(}	t	        j                  dt        |	              |	d}	~	ww xY w# t        $ r0}	dt        |	      v r|s| j%                  ||||	      cY d}	~	S |	d}	~	ww xY w)a  
        Get access token and project id

        1. Check if credentials are already in self._credentials_project_mapping
        2. If not, load credentials and add to self._credentials_project_mapping
        3. Check if loaded credentials have expired
        4. If expired, refresh credentials
        5. Return access token and project id

        Args:
            credentials: The credentials to use for authentication
            project_id: The Google Cloud project ID
            _retry_reauth: Internal flag to prevent infinite recursion during reauthentication

        Returns:
            Tuple of (access_token, project_id)
        Nz,Checking cached credentials for project_id: z)Cached credentials found for project_id: .zcached_entry: %sr!   z+Using cached credentials for project_id: %sz/Credential cache key not found for project_id: z, loading new credentialsr   znFailed to load vertex credentials. Check to see if credentials containing partial/invalid information. Error: zZCould not resolve credentials - either dynamically or from environment, for project_id: {}z'Validating credentials for project_id: z"Credentials are None after loadingz0Credentials expired, refreshing for project_id: zReauthentication is needed)r5   r!   r   r   zFCould not resolve credentials token. Got None or non-string token - {}rB   )rC   rP   rJ   dumpsr	   rE   r    tuplerX   rZ   ra   rN   	exceptionrD   rQ   rO   expiredr\   r   token)r#   r5   r!   r   cache_credentialsr   r   cached_entrycredential_project_ideresolved_cache_keys              r%   r   zVertexBase.get_access_token   s;   4 (2+t'DDJJ{#+ 	 !2:>:>::,G	
  4#D#DD  ;J<qI  <<=QRL  !3\B,.6B33  ,(4(E(E ) ,J%   =%   A*Mfg6:nn +
 7E 733 # pww"  %GD--.BC 	FzlST%10#6.J"3Z!@!)J)JJ )I112DE ABB$$FzlS !!,/ )K112FG" %Z8J8JC-PX__ &&  ;<<!!:--O  (( E  FI  JK  FL  EM  N 	`  
 03q69-88$/#--A	 9   
s<   6I $:I7 	I4#I//I47	J0 #J+#J0)J++J0c                    K   |dk(  ry	  t        | j                        ||       d{   S 7 # t        $ r}|d}~ww xY ww)z7
        Async version of _ensure_access_token
        r   r   r   N)r
   r   rN   )r#   r5   r!   r   r   s        r%   _ensure_access_token_asyncz%VertexBase._ensure_access_token_async  sX      (*<Xd&;&;< +)     s.   A 1 /1 A1 	A<AAextra_headersc                 H    ddi}|d| |d<   ||j                  |       |S )NzContent-Typezapplication/jsonzBearer Authorization)update)r#   r   r   headerss       r%   set_headerszVertexBase.set_headers  sA     .
 ")0'>GO$$NN=)r&   litellm_paramsc                     | j                  dd       xs1 | j                  dd       xs t        j                  xs t        d      S )Nr   vertex_ai_projectVERTEXAI_PROJECT)popr,   r   r   r   s    r%   get_vertex_ai_projectz VertexBase.get_vertex_ai_project  sN     /6 2!!"5t<2%%2 01		
r&   c                 h    | j                  dd       xs | j                  dd       xs t        d      S )Nr   vertex_ai_credentialsVERTEXAI_CREDENTIALS)r   r   r   s    r%   get_vertex_ai_credentialsz$VertexBase.get_vertex_ai_credentials  s>     3T: 6!!"94@645	
r&   c                     | j                  dd       xs> | j                  dd       xs* t        j                  xs t        d      xs t        d      S )Nr   vertex_ai_locationVERTEXAI_LOCATIONVERTEX_LOCATION)r   r,   r   r   r   s    r%   get_vertex_ai_locationz!VertexBase.get_vertex_ai_location  s^     0$7 1!!"6=1&&1 121 /0	
r&   c                     | j                  d      xs0 | j                  d      xs t        j                  xs t        d      S )a  
        Safely get Vertex AI project without mutating the litellm_params dict.

        Unlike get_vertex_ai_project(), this does NOT pop values from the dict,
        making it safe to call multiple times with the same litellm_params.

        Args:
            litellm_params: Dictionary containing Vertex AI parameters

        Returns:
            Vertex AI project ID or None
        r   r   r   )r/   r,   r   r   r   s    r%   safe_get_vertex_ai_projectz%VertexBase.safe_get_vertex_ai_project  sJ     /0 2!!"562%%2 01		
r&   c                 d    | j                  d      xs | j                  d      xs t        d      S )a  
        Safely get Vertex AI credentials without mutating the litellm_params dict.

        Unlike get_vertex_ai_credentials(), this does NOT pop values from the dict,
        making it safe to call multiple times with the same litellm_params.

        Args:
            litellm_params: Dictionary containing Vertex AI parameters

        Returns:
            Vertex AI credentials or None
        r   r   r   )r/   r   r   s    r%   safe_get_vertex_ai_credentialsz)VertexBase.safe_get_vertex_ai_credentials  s:     34 6!!"9:645	
r&   c                     | j                  d      xs= | j                  d      xs* t        j                  xs t        d      xs t        d      S )a  
        Safely get Vertex AI location without mutating the litellm_params dict.

        Unlike get_vertex_ai_location(), this does NOT pop values from the dict,
        making it safe to call multiple times with the same litellm_params.

        Args:
            litellm_params: Dictionary containing Vertex AI parameters

        Returns:
            Vertex AI location/region or None
        r   r   r   r   )r/   r,   r   r   r   s    r%   safe_get_vertex_ai_locationz&VertexBase.safe_get_vertex_ai_location  sZ     01 1!!"671&&1 121 /0	
r&   )r   Nr   )NNNNF)FchatF)F)+__name__
__module____qualname__r   r   rD   r4   r   r   r   ra   rV   rU   rW   rY   r[   r   r   staticmethodr   boolr   r   r\   r   r   rP   r   r   r   r   rN   r   r   r   r   r   r   r   r   r   r   __classcell__)r$   s   @r%   r   r   %   s^   
>.x} .S .S .:d!#$<=d!KSTW=d!	sCxd!N		

2S 
 
8@
	
  #'MMM 'M 	M
 M 3-M 
M M<*!#* "#* !	*
 * '* * * 
*X' ' '67 SM %3
	 
sCx& $ $  $(,)-AE(-H 3-H  !H  !	H 
 H  H  c]H  H  }H  !H  "#H  %W_%=>H  "&H  
x}c!	"H j 7<%+(->
>
 c]>
 !	>

 !>
 "#>
 %%=>>
 >
 %%LM>
 3->
 &.d^>
 #>
 "&>
 
x}c!	">
@/67/ SM/ $	/
 / 
sCx/j $	G.67G. SMG. 	G.
 
sCxG.R67 SM %3
	 
sCx,#C=9A$	 
d 
x} 
 
 
$ 
8C= 
 
 
t 
 
 
 
4 
HSM 
 
( 
t 
 
 
& 
D 
Xc] 
 
r&   r   )!__doc__rJ   rF   typingr   r   r   r   r   r   r,   litellm._loggingr	   #litellm.litellm_core_utils.asyncifyr
   &litellm.llms.custom_httpx.http_handlerr   litellm.secret_managers.mainr   litellm.types.llms.vertex_air   r   common_utilsr   r   r   r   r   rg   google.auth.credentialsr   GoogleCredentialsObjectr   r~   r&   r%   <module>r      sX     	 E E  + 8 C 7 X - 
 N!
 
r&   