o
    ưi                     @   s  d dl 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 d dl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mZ d d	lmZ d d
lmZ d dlmZm Z  d dl!m"Z" d dl#m$Z$m%Z% G dd deZ&G dd de'eZ(dd e(D Z)	dmde'de
e* de(fddZ+de'de	d de,fddZ-de'de	d de,fddZ.de'de,fdd Z/d d!lm	Z	m
Z
 e	d" Z0de'de'fd#d$Z1d%e
e' de'fd&d'Z2de'd(e
e' d%e
e' d)e	d* dee'e'f f
d+d,Z3d-e0de'd.e
e, d(e
e' d%e
e' d)e	d* dee'e'f fd/d0Z4d-e0de'd.e
e, d1e
e' dee'e'f f
d2d3Z5d4ee de,fd5d6Z6dnd7d8Z7dnd9d:Z8dod<e*d=e,fd>d?Z9d<e*de*fd@dAZ:dBee'ef dee'ef fdCdDZ;dndEdFZ<	 dndGee'ef dHe=dee'ef fdIdJZ>	dmdBee'ef dKee' dee'ef fdLdMZ?dndNdOZ@dPdQ ZAdRe'fdSdTZBdUe'de=fdVdWZCdndXdYZDdZe'de
e' fd[d\ZEdZe'de
e' fd]d^ZFdZe'de
e' fd_d`ZGdae'd(e'd%e'de'fdbdcZHdde'dae'd%e
e' d(e
e' dejIf
dedfZJde'de,fdgdhZKG didj djeZLG dkdl dleZMdS )p    N)deepcopy)Enum)	AnyDictListLiteralOptionalSetTupleUnionget_type_hints)verbose_logger)DEFAULT_MAX_RECURSE_DEPTH)unpack_defs)BaseLLMModelInfoBaseTokenCounter)BaseLLMException)AllMessageValues)PartTypeSchema)TokenCountResponse)supports_response_schemasupports_system_messagesc                
       s<   e Zd Z	ddededeeeej	f  f fddZ
  ZS )VertexAIErrorNstatus_codemessageheadersc                    s   t  j|||d d S )N)r   r   r   )super__init__)selfr   r   r   	__class__ Z/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/vertex_ai/common_utils.pyr      s   zVertexAIError.__init__N)__name__
__module____qualname__intstrr   r   r   httpxZHeadersr   __classcell__r"   r"   r    r#   r      s    r   c                   @   s0   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
S )VertexAIModelRoutez Enum for Vertex AI model routingZpartner_modelsgeminiZgemmabgeZmodel_gardenZ
non_geminiopenaiZagent_engineN)r%   r&   r'   __doc__PARTNER_MODELSGEMINIGEMMABGEMODEL_GARDEN
NON_GEMINIZOPENAI_COMPATIBLEAGENT_ENGINEr"   r"   r"   r#   r,      s    r,   c                 C   s   g | ]}|j  d qS )/)value).0router"   r"   r#   
<listcomp>*   s    r<   modellitellm_paramsreturnc                 C   s   ddl m} |r|ddurd|d v rtjS d| v rtjS |  r-|r-|dr-tjS |j| dr6tjS d	| v s@d
| 	 v rCtj
S d| v rJtjS d| v rQtjS d| v rXtjS tjS )a  
    Determine which handler to use for a Vertex AI model based on the model name.

    Args:
        model: The model name (e.g., "llama3-405b", "gemini-pro", "gemma/gemma-3-12b-it", "openai/gpt-oss-120b")
        litellm_params: Optional litellm parameters dict that may contain base_model for routing

    Returns:
        VertexAIModelRoute: The route enum indicating which handler should be used

    Examples:
        >>> get_vertex_ai_model_route("llama3-405b")
        VertexAIModelRoute.PARTNER_MODELS

        >>> get_vertex_ai_model_route("gemini-pro")
        VertexAIModelRoute.GEMINI

        >>> get_vertex_ai_model_route("gemma/gemma-3-12b-it")
        VertexAIModelRoute.GEMMA

        >>> get_vertex_ai_model_route("openai/gpt-oss-120b")
        VertexAIModelRoute.MODEL_GARDEN
        
        >>> get_vertex_ai_model_route("1234567890", {"api_base": "http://10.96.32.8"})
        VertexAIModelRoute.GEMINI  # Numeric endpoints with api_base use HTTP path
    r   VertexAIPartnerModelsZ
base_modelNr-   zagent_engine/api_baser=   zbge/r.   zgemma/r/   )4litellm.llms.vertex_ai.vertex_ai_partner_models.mainrA   getr,   r2   r7   isdigitis_vertex_partner_modelr1   lowerr4   r3   r5   r6   )r=   r>   rA   r"   r"   r#   get_vertex_ai_model_route,   s&   rI   custom_llm_provider)	vertex_aivertex_ai_betar-   c              
   C   sx   z|}|dkr	d}t | |d}tj| rd}W |S W |S  ty; } ztdt| d}W Y d }~|S d }~ww )NrL   rK   r=   rJ   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VertexGeminiConfigZ_is_model_gemini_spec_model	Exceptionr   warningformatr)   )r=   rJ   _custom_llm_providerZsupports_system_messageer"   r"   r#   get_supports_system_messages   s,   	
rU   c                 C   s    |}|dkrd}t | |d}|S )NrL   rK   rM   )r   )r=   rJ   rS   Z_supports_response_schemar"   r"   r#   get_supports_response_schema   s   rV   c                 C   s    |   }td}t||S )a  
    Check if the model supports responseJsonSchema (JSON Schema format).

    responseJsonSchema is supported by Gemini 2.0+ models and uses standard
    JSON Schema format with lowercase types (string, object, etc.) instead of
    the OpenAPI-style responseSchema with uppercase types (STRING, OBJECT, etc.).

    Benefits of responseJsonSchema:
    - Supports additionalProperties for stricter schema validation
    - Uses standard JSON Schema format (no type conversion needed)
    - Better compatibility with Pydantic's model_json_schema()

    Args:
        model: The model name (e.g., "gemini-2.0-flash", "gemini-2.5-pro")

    Returns:
        True if the model supports responseJsonSchema, False otherwise
    zgemini-([2-9]|[1-9]\d+)\.)rH   recompileboolsearch)r=   Zmodel_lowerZgemini_2_plus_patternr"   r"   r#   supports_response_json_schema   s   
r[   )r   r   )chat	embeddingbatch_embeddingimage_generationcount_tokensc                 C   s*   t D ]}| |r| |dd  S q| S )a  
    Strip routing prefixes from model name for PSC/endpoint URL construction.
    
    Patterns like "bge/", "gemma/", "openai/" are used for internal routing but 
    should not appear in the actual endpoint URL. Routing prefixes are derived
    from VertexAIModelRoute enum values.
    
    Args:
        model: The model name with potential prefix (e.g., "bge/123456", "gemma/gemma-3-12b-it")
        
    Returns:
        str: The model name without routing prefix (e.g., "123456", "gemma-3-12b-it")
        
    Examples:
        >>> get_vertex_base_model_name("bge/378943383978115072")
        "378943383978115072"
        
        >>> get_vertex_base_model_name("gemma/gemma-3-12b-it")
        "gemma-3-12b-it"
        
        >>> get_vertex_base_model_name("openai/gpt-oss-120b")
        "gpt-oss-120b"
        
        >>> get_vertex_base_model_name("1234567890")
        "1234567890"
        )VERTEX_AI_MODEL_ROUTES
startswithreplace)r=   r;   r"   r"   r#   get_vertex_base_model_name   s
   
rf   vertex_locationc                 C   s   | dkrdS d|  dS )z3
    Get the base URL for Vertex AI API calls.
    globalz!https://aiplatform.googleapis.comzhttps://z-aiplatform.googleapis.comr"   )rg   r"   r"   r#   get_vertex_base_url   s   ri   vertex_projectvertex_api_version)v1v1beta1c                 C   st   d}t | d} t|}|  r&| d| d| d| d|  d| }||fS | d| d| d	|  d| 	}||fS )
z
    Get URL for embedding models.
    
    Handles special patterns:
    - bge/endpoint_id -> strips to endpoint_id for endpoints/ routing
    - numeric model -> routes to endpoints/
    - regular model -> routes to publishers/google/models/
    predictrC   r8   
/projects//locations//endpoints/:/v1/projects//publishers/google/models/)rf   ri   rF   )r=   rj   rg   rk   endpointbase_urlurlr"   r"   r#   _get_embedding_url   s   
& rx   modestreamc           	      C   st  d }d }t jj|d}| dkrOd}t|}|du rd}| r3| d| d| d| d	| d
| }n| d| d| d| d| d
| }|du rN|d7 }n\| dkr[t||||dS | dkrd}t|}| r}| d| d| d| d	| d
| }n.| d| d| d| d
| 	}n| dkrd}t|}| d| d| d| d| d
| }|r|std|  ||fS )NrC   r\   generateContentTstreamGenerateContentr8   ro   rp   rq   rr   rt   z?alt=sser]   )r=   rj   rg   rk   r_   rn   rs   r`   countTokensz,Unable to get vertex url/endpoint for mode: )rN   rO   Zget_model_for_vertex_ai_urlri   rF   rx   
ValueError)	ry   r=   rz   rj   rg   rk   rw   ru   rv   r"   r"   r#   _get_vertex_url  sD   (&("&r   gemini_api_keyc           	      C   s   ddl m} d|}||rdnd}| dkr8d}|du r,d	}d
||||}||fS d||||}||fS | dkrId}d|||}||fS | dkrZd}d|||}||fS | dkrkd}d|||}||fS | dkrstdtd|  )Nr   )rO   z	models/{}Zv1alphaZv1betar\   r{   Tr|   zAhttps://generativelanguage.googleapis.com/{}/{}:{}?key={}&alt=ssez9https://generativelanguage.googleapis.com/{}/{}:{}?key={}r]   ZembedContentz=https://generativelanguage.googleapis.com/v1beta/{}:{}?key={}r^   ZbatchEmbedContentsr`   r}   r_   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/issueszUnsupported mode: )Z@litellm.llms.vertex_ai.gemini.vertex_and_google_ai_studio_geminirO   rR   Z_is_gemini_3_or_newerr~   )	ry   r=   rz   r   rO   Z_gemini_model_nameapi_versionru   rw   r"   r"   r#   _get_gemini_urlJ  sN   

r   partsc                 C   s,   d}| D ]}d|v r| ddurd}q|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 present (empty strings are valid)
        - Relevant Issue: https://github.com/BerriAI/litellm/issues/5515
    FtextNT)rE   )r   Zhas_text_parampartr"   r"   r#   _check_text_in_content}  s   r   c                 C   s   |t krtdt  dd| v r"t| d tr"dd | d D | d< | dd}|dur=| D ]\}}t||d d	 q0| d
d}|durQt||d d	 dS dS )zkFix empty strings in enum values by replacing them with None. Gemini doesn't accept empty strings in enums.Max depth of " exceeded while processing schema.enumc                 S   s   g | ]
}|d kr
dn|qS )ra   Nr"   )r:   r9   r"   r"   r#   r<     s    z+_fix_enum_empty_strings.<locals>.<listcomp>
propertiesNrb   depthitems)r   r~   
isinstancelistrE   r   _fix_enum_empty_strings)schemar   r   _r9   r   r"   r"   r#   r     s   
r   c                 C   sn  |t krtdt  dt| tsdS d| v rct| d trc| d}d}t|tr3| dkr3d}n(| d	}t|tr[|D ]}t|trZ|d}t|trZ| dkrZd} nq?|sc| dd | d
d}|dur~|	 D ]\}}	t
|	|d d qq| dd}
|
durt
|
|d d | d	d}|durt|tr|D ]}t|trt
||d d qdS dS dS )a+  Remove `enum` fields when the schema type is not string.

    Gemini / Vertex APIs only allow enums for string-typed fields. When an enum
    is present on a non-string typed property (or when `anyOf` types do not
    include a string type), remove the enum to avoid provider validation errors.
    r   r   Nr   typeFstringTanyOfr   rb   r   r   )r   r~   r   dictr   rE   r)   rH   popr   _fix_enum_types)r   r   Zschema_typeZ	keep_enumanyofitemZ	item_typer   r   r9   r   r"   r"   r#   r     sJ   







r   F
parametersadd_property_orderingc                 C   sp   t tt }| di }t| | t|  t|  t|  t	|  t
|  t|  t| |} |r6t|  | 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   keysr   r   convert_anyof_null_to_nullable_convert_schema_typesr   r   process_itemsadd_object_typefilter_schema_fieldsset_schema_property_ordering)r   r   Zvalid_schema_fieldsZdefsr"   r"   r#   _build_vertex_schema  s   

r   c                 C   s   | S )a3  
    Build a JSON Schema for use with Gemini's responseJsonSchema parameter.

    Unlike _build_vertex_schema (used for responseSchema), this function:
    - Does NOT convert types to uppercase (keeps standard JSON Schema format)
    - Does NOT add propertyOrdering
    - Does NOT filter fields (allows additionalProperties)
    - Preserves $defs/$ref (Gemini 2.0+ supports JSON Schema references natively)

    Parameters:
        parameters: dict - the JSON schema to process

    Returns:
        dict - the processed schema in standard JSON Schema format
    r"   )r   r"   r"   r#   _build_json_schema  s   r   schema_dictc                 C   s   |  dd}|  dd}t| trA|  drA| d }|s|r=t|tr=tdd |D r=|D ]}|r6||d< |r<||d< q.d|i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descriptionr   c                 s   s    | ]}t |tV  qd S r$   )r   r   r:   r   r"   r"   r#   	<genexpr>3  s    z'_filter_anyof_fields.<locals>.<genexpr>)rE   r   r   r   all)r   r   r   any_ofr   r"   r"   r#   _filter_anyof_fields!  s(   
r   c                 C   s   |t krtdt  dt| trMd| v r!| d i kr!ddi| d< |  D ])\}}t|tr6t||d  q%t|trL|D ]}t|trKt||d  q=q%d S d S )Nr   Q exceeded while processing schema. Please check the schema for excessive nesting.r   r   objectrb   )r   r~   r   r   r   r   r   )r   r   keyr9   r   r"   r"   r#   r   >  s"   




r   r   r   c                 C   s   |t krtdt  dd| v r:t| d tr:d| vr(dd | d  D | d< | d  D ]\}}t||d  q.d| v rGt| d |d  | S )	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   r   ZpropertyOrderingc                 S   s   g | ]\}}|qS r"   r"   r:   kvr"   r"   r#   r<   d  s    z0set_schema_property_ordering.<locals>.<listcomp>rb   r   )r   r~   r   r   r   r   )r   r   r   r   r"   r"   r#   r   O  s   
r   valid_fieldsc                    s
   du rt   t| }| v r| S  | t| ts| S i }t| } |  D ][\}}|vr0q'|dkrHt|trH fdd| D ||< q'|dkrV|dv rU|||< q'q'|dkrht|trht| ||< q'|dkr~t|tr~ fd	d
|D ||< q'|||< q'|S )zK
    Recursively filter a schema dictionary to keep only valid fields.
    Nr   c                    s   i | ]\}}|t | qS r"   r   r   	processedr   r"   r#   
<dictcomp>  s    z(filter_schema_fields.<locals>.<dictcomp>rR   >   z	date-timer   r   r   c                    s   g | ]}t | qS r"   r   r   r   r"   r#   r<     s    z(filter_schema_fields.<locals>.<listcomp>)	r   idaddr   r   r   r   r   r   )r   r   r   Z	schema_idresultr   r9   r"   r   r#   r   l  s:   



r   c           	      C   s4  |t krtdt  d	 | dd }|d urid}|D ]$}t|tr1|ddkr1|| d}qd|vr?t|dkr?d	|d< qt|dkrJtd
|ri|D ]}|ddkrdd|v rd|d sd|d d|d< qN| dd }|d ur| D ]\}}t	||d d qw| dd }|d urt	||d d d S d S )Nr   r   r   Fr   nullTr   r   zaInvalid input: AnyOf schema with only null type is not supported. Please provide a non-null type.arrayr   Znullabler   rb   r   )
r   r~   rE   r   r   removelenr   r   r   )	r   r   r   Zcontains_nullZatyper   namer9   r   r"   r"   r#   r     sF   



r   c                 C   s  d| vrd| vrd| vrd| vrd| d< |  dd }|d urRd| v r.| d d u r.| dd  |sA| dd  | dd  d| d< nd| d< | D ]\}}t| qI|  dd }|d ur`t| d	D ]}|  |d }|d urt|tr|D ]}t|trt| quqbd S )
Nr   r   oneOfallOfr   r   requiredr   )r   r   r   )rE   r   r   r   r   r   r   )r   r   r   r9   r   r   valuesr"   r"   r#   r     s0    


r   
field_namec                 C   sb   |  |d  | dd }|d ur| D ]	\}}t|| q| dd }|d ur/t|| d S d S )Nr   r   )r   rE   r   strip_field)r   r   r   r   r9   r   r"   r"   r#   r     s   r   vertex_datetimec                 C   s$   ddl m } || d}t| 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   dtr"   r"   r#   +_convert_vertex_datetime_to_openai_datetime  s   r   c                 C   s  |t krtdt  dt| tsdS d| v r| d }t|trt|dkrh d}g }|D ]:}t|ts6q.|dkrB|ddi q.|dv rad|i}|D ]}|| v rZt| | ||< qL|| q.|d|i q.t	d	d
 |D }|r|D ]}| 
|d qv|| d< | 
d nt|trt|dkr|d | d< n	t|tr|| d< dD ]C}	|	| v r| |	 }
|	dkrt|
tr|
 D ]	}t||d  qq|	dkrt|
|d  q|	dkrt|
tr|
D ]	}t||d  qqdS )z
    Convert type arrays and lowercase types for Vertex AI compatibility.

    Transforms OpenAI-style schemas to Vertex AI format by converting type arrays
    like ["string", "number"] to anyOf format and converting all types to uppercase.
    r   r   Nr   rb   >   ZmaxPropertiesZadditionalPropertiesr   ZminItemsr   ZminPropertiesZmaxItemsr   r   r   r   c                 s   s"    | ]}t |tr|d v V  qdS )r   N)r   r)   )r:   tr"   r"   r#   r   3  s     z(_convert_schema_types.<locals>.<genexpr>r   r   )r   r   r   r   r   )r   r~   r   r   r   r   r)   appendr   anyr   r   r   )r   r   Ztype_valZtype_specific_fieldsr   r   Zitem_schemafieldZhas_object_or_arrayr   r9   Zprop_schemaZanyof_schemar"   r"   r#   r     sb   



r   rw   c                 C      t d| }|r|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/([^/]+)rb   NrW   rZ   grouprw   matchr"   r"   r#   get_vertex_project_id_from_urlM     r   c                 C   r   )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/([^/]+)rb   Nr   r   r"   r"   r#   get_vertex_location_from_urlW  r   r   c                 C   r   )z
    Get the vertex model id from the url

    `https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:streamGenerateContent`
    z/models/([^:]+)rb   Nr   r   r"   r"   r#   get_vertex_model_id_from_urla  r   r   requested_routec                 C   s    t dd| d| d| }|S )zS
    Replace project and location values in the route with the provided values
    z /projects/[^/]+/locations/[^/]+/ro   rp   r8   )rW   sub)r   rj   rg   Zmodified_router"   r"   r#   %replace_project_and_location_in_routek  s   r   rv   c           	      C   s   t | }d|v r|r|rt|||}|j|dS 	 d}d|v r"d}|dr1d}|ddd}n|d	r?d}|d	dd}d
|||}d| | }|j|d}|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)pathrl   ZcachedContentrm   z/v1/r8   rb   z	/v1beta1/z{}/projects/{}/locations/{})r*   URLr   	copy_withrd   re   rR   )	rv   r   rg   rj   Znew_base_urlZvertex_versionZbase_requested_routeZupdated_requested_routeZupdated_urlr"   r"   r#   construct_target_urlz  s.   


r   c                 C   s,   ddl m} || dd}|du rdS 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_regionsrK   rM   NFrh   )litellm.utilsr   )r=   r   Zsupported_regionsr"   r"   r#   is_global_only_vertex_model  s   
r   c                   @   s   e Zd Zdee fddZ		ddededee	 ded	ed
ee dee defddZ
	dd
ee dee dee fddZedd
ee dee fddZe	ddee dee fddZededee fddZdS )VertexAIModelInfor?   c                 C   s   t  S )z
        Factory method to create a token counter for this provider.

        Returns:
            Optional TokenCounterInterface implementation for this provider,
            or None if token counting is not supported.
        VertexAITokenCounter)r   r"   r"   r#   get_token_counter  s   z#VertexAIModelInfo.get_token_counterNr   r=   messagesoptional_paramsr>   api_keyrB   c                 C      t dN&Vertex AI models are not supported yetNotImplementedError)r   r   r=   r   r   r>   r   rB   r"   r"   r#   validate_environment  s   
z&VertexAIModelInfo.validate_environmentc                 C   r   )zF
        Returns a list of models supported by this provider.
        r   r   )r   r   rB   r"   r"   r#   
get_models  s   zVertexAIModelInfo.get_modelsc                 C   r   r   r   )r   r"   r"   r#   get_api_key  s   zVertexAIModelInfo.get_api_keyc                 C   r   r   r   )rB   r"   r"   r#   get_api_base  s   zVertexAIModelInfo.get_api_basec                 C   r   )a2  
        Returns the base model name from the given model name.

        Some providers like bedrock - can receive model=`invoke/anthropic.claude-3-opus-20240229-v1:0` or `converse/anthropic.claude-3-opus-20240229-v1:0`
            This function will return `anthropic.claude-3-opus-20240229-v1:0`
        r   r   rC   r"   r"   r#   get_base_model  s   z VertexAIModelInfo.get_base_model)NNr$   )r%   r&   r'   r   r   r   r   r)   r   r   r   r   staticmethodr   r   r   r"   r"   r"   r#   r     sP    	

r   c                   @   s   e Zd ZdZ	ddee defddZ				dded	eee	ee
f   d
eee	ee
f   dee	ee
f  dedeee	ee
f   dee
 dee fddZdS )r   z;Token counter implementation for Google AI Studio provider.NrJ   r?   c                 C   s   ddl m} ||jjkS )Nr   )LlmProviders)litellm.types.utilsr   Z	VERTEX_AIr9   )r   rJ   r   r"   r"   r#   should_use_token_counting_api  s   z2VertexAITokenCounter.should_use_token_counting_apira   model_to_user   contents
deploymentrequest_modeltoolssystemc                    s>  dd l }ddlm}	 |pi }||di }
|	|rl|	 }|
dp)|
d}|
dp3|
d}|
dp:|}|
d	pD|
d
}|j||pKg |
|||dI d H }|d urjt|dd|||dd|dS d S ddlm	} ||d}|

| | jdi |
I d H }|d urt|dd|||dd|dS d S )Nr   r@   r>   rj   Zvertex_ai_projectrg   Zvertex_ai_locationZvertex_count_tokens_locationvertex_credentialsZvertex_ai_credentials)r=   r   r>   rj   rg   r  Zinput_tokensZtokenizer_usedra   )Ztotal_tokensr   Z
model_usedZtokenizer_typeoriginal_responser   )r=   r   ZtotalTokensr"   )copyrD   rA   r   rE   rG   r`   r   Z+litellm.llms.vertex_ai.count_tokens.handlerr   updateZacount_tokens)r   r   r   r   r   r   r   r  r  rA   Zcount_tokens_params_requestZpartner_models_handlerrj   rg   r  r   r   Zcount_tokens_paramsr"   r"   r#   r`     s~   


	





z!VertexAITokenCounter.count_tokensr$   )Nra   NN)r%   r&   r'   r0   r   r)   rY   r   r   r   r   r   r`   r"   r"   r"   r#   r     s:    
	r   r$   )r   )F)NrW   r  r   r   r   typingr   r   r   r   r   r	   r
   r   r   r*   rN   Zlitellm._loggingr   Zlitellm.constantsr   Z8litellm.litellm_core_utils.prompt_templates.common_utilsr   Z litellm.llms.base_llm.base_utilsr   r   Z)litellm.llms.base_llm.chat.transformationr   Zlitellm.types.llms.openair   Zlitellm.types.llms.vertex_air   r   r   r   r   r   r   r   r)   r,   rc   r   rI   rY   rU   rV   r[   Zall_gemini_url_modesrf   ri   rx   r   r   r   r   r   r   r   r   r   r(   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r"   r"   r"   r#   <module>   s   ,

G

$


#

:

3

33"







./!
G




54