Ë
    uPêj:(  ã                   óv   — 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mZ d dl­ d dlmZ  G d„ d	«      Zy
)é    )ÚAnyÚFinal)Úunquote)Úuuid)ÚVertexAIErrorÚ+_convert_vertex_datetime_to_openai_datetime)ÚBatchJobStatusÚCreateBatchRequest)Ú*)ÚLiteLLMBatchc                   óh  — e Zd ZdZededefd„«       Zedede	fd„«       Z
edeeef   deeef   fd„«       Zededefd„«       Zededefd	„«       Zededefd
„«       Zededefd„«       Zededefd„«       Zededefd„«       Zedededz  fd„«       Zededz  defd„«       Zededefd„«       Zy)ÚVertexAIBatchTransformationz­
    Transforms OpenAI Batch requests to Vertex AI Batch requests

    API Ref: https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/batch-prediction-gemini
    ÚrequestÚreturnc                 ó(  — dt        j                  «       › �}|j                  d«      }|€t        d«      ‚t	        t        |g¬«      d¬«      }| j                  |«      }t        dt        | j                  |«      ¬«      ¬«      }t        ||||¬	«      S )
zN
        Transforms OpenAI Batch requests to Vertex AI Batch requests
        zlitellm-vertex-batch-Úinput_file_idz+input_file_id is required, but not provided)ÚurisÚjsonl)Ú	gcsSourceÚinstancesFormat)ÚoutputUriPrefix)ÚpredictionsFormatÚgcsDestination)ÚinputConfigÚoutputConfigÚmodelÚdisplayName)r   Úuuid4ÚgetÚ
ValueErrorÚInputConfigÚ	GcsSourceÚ_get_model_from_gcs_fileÚOutputConfigÚGcsDestinationÚ_get_gcs_uri_prefix_from_fileÚVertexAIBatchPredictionJob)Úclsr   Úrequest_display_namer   Úinput_configr   Úoutput_configs          úr/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/vertex_ai/batches/transformation.pyÚ9transform_openai_batch_request_to_vertex_ai_batch_requestzUVertexAIBatchTransformation.transform_openai_batch_request_to_vertex_ai_batch_request   s—   € ð )>¼d¿j¹j»l¸^Ð&LÐØ&Ÿ{™{¨?Ó;ˆØÐ ÜÐJÓKÐKÜ$/¼)È-ÈÔ:YÐkrÔ$sˆØ×8Ñ8¸ÓGˆÜ-9Ø%Ü)¸#×:[Ñ:[Ð\iÓ:jÔkô.
ˆô *Ø$Ø&ØØ,ô	
ð 	
ó    Úresponsec                 óÖ   — t        | j                  |«      dt        |j                  dd«      ¬«      d| j	                  |«      d| j                  |«      d | j                  |«      ¬«	      S )NÚ24hÚ
createTimeÚ )Úvertex_datetimeÚbatch)	ÚidÚcompletion_windowÚ
created_atÚendpointr   ÚobjectÚstatusÚerror_file_idÚoutput_file_id)r   Ú+_get_batch_id_from_vertex_ai_batch_responser   r   Ú0_get_input_file_id_from_vertex_ai_batch_responseÚ3_get_batch_job_status_from_vertex_ai_batch_responseÚ1_get_output_file_id_from_vertex_ai_batch_response)r(   r/   s     r,   Ú;transform_vertex_ai_batch_response_to_openai_batch_responsezWVertexAIBatchTransformation.transform_vertex_ai_batch_response_to_openai_batch_response.   sn   € ô Ø×>Ñ>¸xÓHØ#ÜBÐS[×S_ÑS_Ð`lÐnpÓSqÔrØØ×NÑNÈxÓXØØ×JÑJÈ8ÓTØØ×PÑPÐQYÓZô

ð 
	
r.   c                 ó6  — |j                  dg «      xs g }|D �cg c]  }| j                  |«      ‘Œ }}t        |«      dkD  r|d   j                  nd}t        |«      dkD  r|d   j                  nd}|j                  d«      }d|||t	        |«      |dœS c c}w )z`
        Transforms Vertex AI batch list response into OpenAI-compatible list response.
        ÚbatchPredictionJobsr   NéÿÿÿÿÚnextPageTokenÚlist)r:   ÚdataÚfirst_idÚlast_idÚhas_moreÚnext_page_token)r   rB   Úlenr6   Úbool)r(   r/   Ú
batch_jobsÚjobrH   rI   rJ   rL   s           r,   Ú?transform_vertex_ai_batch_list_response_to_openai_list_responsez[VertexAIBatchTransformation.transform_vertex_ai_batch_list_response_to_openai_list_response>   s£   € ð %ŸL™LÐ)>ÀÓCÒIÀrˆ
ØgqÖrÐ`c�s×VÑVÐWZÕ[ÐrˆÐrä(+¨D«	°Aª˜$˜q™'Ÿ*š*¸4ˆÜ(+¨D«	°Aª˜˜b™Ÿš¸4ˆØ!)§¡¨oÓ!>ˆð ØØ ØÜ˜_Ó-Ø.ñ
ð 	
ùò ss   ›Bc                 ó`   — |j                  dd«      }|sy|j                  d«      }|r|d   S |S )zã
        Gets the batch id from the Vertex AI Batch response safely

        vertex response: `projects/510528649030/locations/us-central1/batchPredictionJobs/3814889423749775360`
        returns: `3814889423749775360`
        Únamer3   ú/rE   )r   Úsplit)r(   r/   Ú_nameÚpartss       r,   r>   zGVertexAIBatchTransformation._get_batch_id_from_vertex_ai_batch_responseV   s;   € ð  —|‘| F¨BÓ/ˆÙØð —{‘{ 3Ó'ˆÙ!ˆu�R‰yÐ, uÐ,r.   c                 ó¨   — d}|j                  d«      }|€|S |j                  d«      }|€|S |j                  dd«      }t        |«      dk(  r|S |d   S )zJ
        Gets the input file id from the Vertex AI Batch response
        r3   r   r   r   r   )r   rM   )r(   r/   r   r*   Ú
gcs_sourcer   s         r,   r?   zLVertexAIBatchTransformation._get_input_file_id_from_vertex_ai_batch_responsef   si   € ð
 %'ˆØ&Ÿl™l¨=Ó9ˆØÐØ Ð à(×,Ñ,¨[Ó9ˆ
ØÐØ Ð à —n‘n V¨RÓ0ˆÜˆt‹9˜Š>Ø Ð à�A‰wˆr.   c                 ód  — |j                  d«      xs
 t        «       }|j                  dd«      }|r|j                  d«      dz   }|r|dk7  r|S |j                  d«      }|€|S |j                  d«      }|€|S |j                  dd«      }|j                  d«      r|S |j                  d«      dz   S )	zK
        Gets the output file id from the Vertex AI Batch response
        Ú
outputInfoÚgcsOutputDirectoryr3   rT   z/predictions.jsonlr   r   r   )r   Ú
OutputInfoÚrstripÚendswith)r(   r/   Úoutput_infor=   r+   Úgcs_destinationÚoutput_uri_prefixs          r,   rA   zMVertexAIBatchTransformation._get_output_file_id_from_vertex_ai_batch_responsez   sË   € ð &Ÿ\™\¨,Ó7ÒG¼:»<ˆØ)Ÿo™oÐ.BÀBÓGˆÙØ+×2Ñ2°3Ó7Ð:NÑNˆNÙ˜nÐ0DÒDØ!Ð!à'Ÿ|™|¨NÓ;ˆØÐ Ø!Ð!à!.×!2Ñ!2Ð3CÓ!DˆØÐ"Ø!Ð!à#2×#6Ñ#6Ð7HÈ"Ó#MÐØ×%Ñ%Ð&:Ô;Ø$Ð$Ø ×'Ñ'¨Ó,Ð/CÑCÐCr.   c                 óN   — dddddddddddddœ}|j                  d	d
«      }||   S )zž
        Gets the batch job status from the Vertex AI Batch response

        ref: https://cloud.google.com/vertex-ai/docs/reference/rest/v1/JobState
        ÚfailedÚ
validatingÚin_progressÚ	completedÚ
cancellingÚ	cancelledÚexpired)ÚJOB_STATE_UNSPECIFIEDÚJOB_STATE_QUEUEDÚJOB_STATE_PENDINGÚJOB_STATE_RUNNINGÚJOB_STATE_SUCCEEDEDÚJOB_STATE_FAILEDÚJOB_STATE_CANCELLINGÚJOB_STATE_CANCELLEDÚJOB_STATE_PAUSEDÚJOB_STATE_EXPIREDÚJOB_STATE_UPDATINGÚJOB_STATE_PARTIALLY_SUCCEEDEDÚstaterk   )r   )r(   r/   Ústate_mappingÚvertex_states       r,   r@   zOVertexAIBatchTransformation._get_batch_job_status_from_vertex_ai_batch_response”   sM   € ð &.Ø ,Ø!-Ø!.Ø#.Ø (Ø$0Ø#.Ø -Ø!*Ø"/Ø-8ñ;
ˆð 'Ÿl™l¨7Ð4KÓLˆØ˜\Ñ*Ð*r.   r   c                 ó0   — |j                  dd«      }|d   S )aK  
        Gets the gcs uri prefix from the input file id

        Example:
        input_file_id: "gs://litellm-testing-bucket/vtx_batch.jsonl"
        returns: "gs://litellm-testing-bucket"

        input_file_id: "gs://litellm-testing-bucket/batches/vtx_batch.jsonl"
        returns: "gs://litellm-testing-bucket/batches"
        rT   é   r   )Úrsplit)r(   r   Ú
path_partss      r,   r&   z9VertexAIBatchTransformation._get_gcs_uri_prefix_from_file¯   s    € ð *×0Ñ0°°aÓ8ˆ
Ø˜!‰}Ðr.   Úgcs_file_uric                 óN   — | j                  |«      }|€t        dd|› d�¬«      ‚|S )aW  
        Extracts the model from the gcs file uri

        When files are uploaded using LiteLLM (/v1/files), the model is stored in the gcs file uri

        Why?
        - Because Vertex Requires the `model` param in create batch jobs request, but OpenAI does not require this


        gcs_file_uri format: gs://litellm-testing-bucket/litellm-vertex-files/publishers/google/models/gemini-1.5-flash-001/e9412502-2c91-42a6-8e61-f5c294cc0fc8
        returns: "publishers/google/models/gemini-1.5-flash-001"

        Raises a 400 `VertexAIError` when the uri carries no parseable model path.
        i�  zPVertex AI batch creation requires the model to be part of `input_file_id`, but 'a6  ' contains no 'publishers/<publisher>/models/<model>' path segment. Either upload the input file through LiteLLM (POST /v1/files with custom_llm_provider=vertex_ai), which encodes the model into the returned file id, or pass a uri of the form gs://<bucket>/<prefix>/publishers/<publisher>/models/<model>/<file>)Ústatus_codeÚmessage)Ú_parse_model_from_gcs_filer   )r(   r~   r   s      r,   r#   z4VertexAIBatchTransformation._get_model_from_gcs_file¿   sF   € ð  ×5Ñ5°lÓCˆØˆ=ÜØðØ$�~ð &ZðZô
ð 
ð ˆr.   Nc                 óÌ   — t        |«      j                  d«      \  }}}|sy|j                  d«      }t        |«      dk  s|d   dk7  s|d   syddj	                  |dd «      › �S )z‹
        Returns the `publishers/<publisher>/models/<model>` path from a gcs uri, or None if the uri
        does not contain one.
        zpublishers/NrT   é   r{   Úmodelsé   )r   Ú	partitionrU   rM   Újoin)r(   r~   Ú_Ú	separatorÚ
model_pathrW   s         r,   r‚   z6VertexAIBatchTransformation._parse_model_from_gcs_fileÞ   sr   € ô $+¨<Ó#8×#BÑ#BÀ=Ó#QÑ ˆˆ9�jÙØà!×'Ñ'¨Ó,ˆÜˆu‹:˜Š>˜U 1™X¨Ò1¸¸qºØà˜SŸX™X e¨B¨Q iÓ0Ð1Ð2Ð2r.   c                 óZ   — |duxr& |j                  d«      xr | j                  |«      duS )zà
        Returns True if `input_file_id` is a raw gs:// Vertex batch input file (i.e. not a
        LiteLLM-managed unified file id) with a `publishers/` model path that
        `_get_model_from_gcs_file` can parse.
        Nzgs://)Ú
startswithr‚   )r(   r   s     r,   Ú$is_unmanaged_gcs_batch_input_file_idz@VertexAIBatchTransformation.is_unmanaged_gcs_batch_input_file_idî   s>   € ð  Ð%ò JØ×(Ñ(¨Ó1òJà×.Ñ.¨}Ó=ÀTÐIð	
r.   c                 óJ   — | j                  |«      j                  dd«      d   S )za
        Extracts the bare model name (e.g. "gemini-1.5-flash-001") from a gcs file uri.
        rT   r{   rE   )r#   r|   )r(   r~   s     r,   Ú!get_bare_model_name_from_gcs_filez=VertexAIBatchTransformation.get_bare_model_name_from_gcs_fileû   s'   € ð
 ×+Ñ+¨LÓ9×@Ñ@ÀÀaÓHÈÑLÐLr.   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Úclassmethodr
   r'   r-   ÚVertexBatchPredictionResponser   rB   ÚdictÚstrr   rQ   r>   r?   rA   r	   r@   r&   r#   r‚   rN   rŽ   r�   © r.   r,   r   r      sÐ  „ ñð ð
à#ð
ð 
$ò
ó ð
ð0 ð
Ø4ð
à	ò
ó ð
ð ð
Ø˜C ˜H‘~ð
à	ˆc�3ˆh‰ò
ó ð
ð. ð-ÐC`ð -Ðehò -ó ð-ð ðÐHeð Ðjmò ó ðð& ðDÐIfð DÐknò Dó ðDð2 ð+Ø4ð+à	ò+ó ð+ð4 ð¸#ð À#ò ó ðð ð°Cð ¸Cò ó ðð< ð3°cð 3¸cÀD¹jò 3ó ð3ð ð

ÀÀtÁð 

ÐPTò 

ó ð

ð ðM¸Sð MÀSò Mó ñMr.   r   N)Útypingr   r   Úurllib.parser   Úlitellm._uuidr   Ú#litellm.llms.vertex_ai.common_utilsr   r   Úlitellm.types.llms.openair	   r
   Úlitellm.types.llms.vertex_aiÚlitellm.types.utilsr   r   r™   r.   r,   ú<module>r¡      s-   ðß Ý  å ÷÷ IÜ *Ý ,÷rMò rMr.   