Ë
    uPêjú7  ã                   óÐ   — d Z ddlZddlmZmZmZ ddl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 ddlmZmZmZmZmZ ddlmZ ddlmZ  G d„ dee«      Z y)zv
Supports writing files to Google AI Studio Files API.

For vertex ai, check out the vertex_ai/files/handler.py file.
é    N)ÚAnyÚFinalÚLiteral)Úurlparse)ÚFileDeleted)Úverbose_logger)Úextract_file_data)Úencode_url_path_segment)ÚBaseFilesConfigÚLiteLLMLoggingObj)ÚGeminiCreateFilesResponseObject)ÚAllMessageValuesÚCreateFileRequestÚHttpxBinaryResponseContentÚ%OpenAICreateFileRequestOptionalParamsÚOpenAIFileObject)ÚLlmProvidersé   )ÚGeminiModelInfoc                   óž  — e Zd Zd„ Zedefd„«       Z	 	 d#deeef   de	de
e   deeef   d	eeef   d
e	dz  de	dz  deeef   fd„Z	 d$de	dz  d
e	dz  de	ded	ededz  de	fd„Zde	de
e   fd„Zdedede	dedef
d„Zde	deded	edef
d„Zde	dz  dej*                  ded	edef
d„Zde	ded	edee	ef   fd„Zde	de	fd„Zdej*                  ded	edefd„Zde	ded	edee	ef   fd„Zdej*                  ded	edefd„Zde	dz  ded	edee	ef   fd„Z dej*                  ded	ede
e   fd „Z!ded	edee	ef   fd!„Z"dej*                  ded	ede#fd"„Z$y)%ÚGoogleAIStudioFilesHandlerc                  ó   — y ©N© ©Úselfs    úm/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/gemini/files/transformation.pyÚ__init__z#GoogleAIStudioFilesHandler.__init__#   s   € Øó    Úreturnc                 ó"   — t         j                  S r   )r   ÚGEMINIr   s    r   Úcustom_llm_providerz.GoogleAIStudioFilesHandler.custom_llm_provider&   s   € ä×"Ñ"Ð"r   NÚheadersÚmodelÚmessagesÚoptional_paramsÚlitellm_paramsÚapi_keyÚapi_basec                 óL   — | j                  |«      }|st        d«      ‚||d<   |S )z‘
        Validate environment and add Gemini API key to headers.
        Google AI Studio uses x-goog-api-key header for authentication.
        z?GEMINI_API_KEY is required for Google AI Studio file operationszx-goog-api-key)Úget_api_keyÚ
ValueError)	r   r$   r%   r&   r'   r(   r)   r*   Úresolved_api_keys	            r   Úvalidate_environmentz/GoogleAIStudioFilesHandler.validate_environment*   s4   € ð #'×"2Ñ"2°7Ó";ÐÙÜÐ^Ó_Ð_à$4ˆÐ Ñ!Øˆr   Ústreamc                 ó¼   — d}| j                  |«      }|st        d«      ‚|xs# |j                  d«      xs | j                  «       }|st        d«      ‚|› d|› �}	|	S )z{
        OPTIONAL

        Get the complete url for the request

        Some providers need `model` in `api_base`
        zupload/v1beta/filesúapi_base is requiredr)   úapi_key is requiredú/)Úget_api_baser-   Úgetr,   )
r   r*   r)   r%   r'   r(   r0   ÚendpointÚfinal_api_keyÚurls
             r   Úget_complete_urlz+GoogleAIStudioFilesHandler.get_complete_url?   sq   € ð  0ˆØ×$Ñ$ XÓ.ˆÙÜÐ3Ó4Ð4ð  'Ò]¨.×*<Ñ*<¸YÓ*GÒ]È4×K[ÑK[ÓK]ˆÙÜÐ2Ó3Ð3à �z  8 *Ð-ˆØˆ
r   c                 ó   — g S r   r   )r   r%   s     r   Úget_supported_openai_paramsz6GoogleAIStudioFilesHandler.get_supported_openai_params\   s   € Øˆ	r   Únon_default_paramsÚdrop_paramsc                 ó   — |S r   r   )r   r=   r'   r%   r>   s        r   Úmap_openai_paramsz,GoogleAIStudioFilesHandler.map_openai_params_   s
   € ð Ðr   Úcreate_file_datac                 ó\  — |j                  d«      }|€t        d«      ‚t        |«      }t        |d   «      }ddt	        |«      |d   ddœ}|j                  |d	   «       dd
|d   xs& t	        t        t        j                  «       «      «      ii}	t	        |«      dddœ}
||	dœ|
|d   dœdœS )zº
        Transform the OpenAI-style file creation request into Gemini's format

        Returns:
            dict: Contains both request data and headers for the two-step upload
        ÚfilezFile data is requiredÚcontentÚ	resumableÚstartÚcontent_typezapplication/json)zX-Goog-Upload-ProtocolúX-Goog-Upload-Commandz#X-Goog-Upload-Header-Content-Lengthz!X-Goog-Upload-Header-Content-TypezContent-Typer$   Údisplay_nameÚfilenameÚ0zupload, finalize)zContent-LengthzX-Goog-Upload-OffsetrH   )r$   Údata)Úinitial_requestÚupload_request)r6   r-   r	   ÚlenÚstrÚupdateÚintÚtime)r   r%   rA   r'   r(   Ú	file_dataÚextracted_dataÚ	file_sizer$   Úinitial_dataÚupload_headerss              r   Útransform_create_file_requestz8GoogleAIStudioFilesHandler.transform_create_file_requesth   sâ   € ð ,×/Ñ/°Ó7ˆ	ØÐÜÐ4Ó5Ð5ô !2°)Ó <ˆô ˜~¨iÑ8Ó9ˆ	ð '2Ø%,Ü36°y³>Ø1?ÀÑ1OØ.ñ
ˆð 	�‰�~ iÑ0Ô1ð  &¨¸ÀzÑ8RÒ8kÔVYÔZ]Ô^b×^gÑ^gÓ^iÓZjÓVkÐ'lÐmˆô " )›nØ$'Ø%7ñ!
ˆð ,3¸LÑIà)Ø& yÑ1ññ
ð 	
r   Úraw_responseÚlogging_objc                 ó”  — 	 |j                  «       }t        di |j                  di «      ¤Ž}t        |d   t	        |d   «      t	        t        j                  t        j                  |d   j                  dd«      d«      «      «      |d   dd	d
d¬«      S # t        $ r)}t        j                  d|«       t        d|› �«      ‚d}~ww xY w)zV
        Transform Gemini's file upload response into OpenAI-style FileObject
        rC   ÚuriÚ	sizeBytesÚ
createTimeÚZú+00:00ú%Y-%m-%dT%H:%M:%S.%f%zÚdisplayNameÚ	user_dataÚuploadedN©ÚidÚbytesÚ
created_atrJ   ÚobjectÚpurposeÚstatusÚstatus_detailsz&Error parsing file upload response: %sz$Error parsing file upload response: r   )Újsonr   r6   r   rR   rS   ÚmktimeÚstrptimeÚreplaceÚ	Exceptionr   Ú	exceptionr-   )r   r%   rZ   r[   r(   Úresponse_jsonÚresponse_objectÚes           r   Útransform_create_file_responsez9GoogleAIStudioFilesHandler.transform_create_file_responseœ   sÜ   € ð	IØ#/×#4Ñ#4Ó#6ˆMä%DÑ%eÀ}×GXÑGXÐY_ÐacÓGdÑ%eˆOô $Ø" 5Ñ)Ü˜/¨+Ñ6Ó7ÜÜ—K‘KÜŸ™Ø+¨LÑ9×AÑAÀ#ÀxÓPØ4óóóð )¨Ñ7ØØ#Ø!Ø#ôð øô" ò 	IÜ×$Ñ$Ð%MÈqÔQÜÐCÀAÀ3ÐGÓHÐHûð	Iús   ‚BB Â	CÂ$CÃCÚfile_idc                 ó  — |j                  d«      xs | j                  «       }|st        d«      ‚| j                  |«      }| j	                  |j                  d«      «      xs d}|j                  d«      }|› d|› �}|i fS )aÐ  
        Get the URL to retrieve a file from Google AI Studio.

        Endpoint:
        GET https://generativelanguage.googleapis.com/v1beta/{name=files/*}

        The URL should look like:
        https://generativelanguage.googleapis.com/v1beta/files/{file_id}?key=API_KEY

        We expect file_id to be just the file identifier (e.g., files/abc123 or abc123)
        as returned by the upload response. (If it's a full URL, extract the file name.)
        r)   r3   r*   z)https://generativelanguage.googleapis.comr4   ú/v1beta/)r6   r,   r-   Ú_normalize_gemini_file_idr5   Úrstrip)r   rx   r'   r(   r)   Ú	file_partr*   r9   s           r   Útransform_retrieve_file_requestz:GoogleAIStudioFilesHandler.transform_retrieve_file_requestÂ   s‹   € ð$ (×+Ñ+¨IÓ6ÒL¸$×:JÑ:JÓ:LˆÙÜÐ2Ó3Ð3à×9Ñ9¸'ÓBˆ	à×$Ñ$ ^×%7Ñ%7¸
Ó%CÓDÒsÐHsˆØ—?‘? 3Ó'ˆà �z ¨)¨Ð5ˆð �Bˆwˆr   c                 ó<  — |j                  d«      rEt        |«      }|j                  j                  d«      }|j	                  d«      }|dk7  r||d }n|}n|}|j                  d«      }|j                  d«      r|j                  d«      }t        |d¬«      }d|› �S )zÌ
        Normalize file identifier into `files/{id}` form.

        Supports:
        - `abc123`
        - `files/abc123`
        - `https://generativelanguage.googleapis.com/v1beta/files/abc123`
        )zhttp://zhttps://r4   úfiles/éÿÿÿÿNrx   )Ú
field_name)Ú
startswithr   ÚpathÚlstripÚfindÚstripÚremoveprefixr
   )r   rx   Úparsedr„   Úfiles_indexÚnormalized_file_idÚencoded_file_ids          r   r{   z4GoogleAIStudioFilesHandler._normalize_gemini_file_idâ   s¬   € ð ×ÑÐ5Ô6Ü$ WÓ-ˆFØ Ÿ+™+×,Ñ,¨SÓ1ˆDØ!%§¡¨8Ó!4ˆKØ˜bÒ Ø%)¨+¨,Ð%7Ñ"à%)Ñ"à!(Ðà/×5Ñ5°cÓ:ÐØ×(Ñ(¨Ô2Ø!3×!@Ñ!@ÀÓ!JÐä!8Ð9KÐXaÔ!bˆà˜Ð(Ð)Ð)r   c                 óª  — 	 t        j                  d|j                  «       |j                  «       }t        j                  d|«       |j	                  dd«      }|dk(  rd}n
|dk(  rd}nd	}t        |j	                  d
d«      t        |j	                  dd«      «      t        t        j                  t        j                  |d   j                  dd«      d«      «      «      |j	                  dd«      dd||dk(  r t        |j	                  dd«      «      ¬«      S d¬«      S # t        $ r)}t        j                  d|«       t        d|› �«      ‚d}~ww xY w)zY
        Transform Gemini's file retrieval response into OpenAI-style FileObject
        zRetrieve file response: %szResponse JSON: %sÚstateÚSTATE_UNSPECIFIEDÚACTIVEÚ	processedÚFAILEDÚerrorre   r]   Ú r^   r   r_   r`   ra   rb   rc   rC   rd   Nrf   z(Error parsing file retrieve response: %sz&Error parsing file retrieve response: )r   ÚdebugÚtextrn   r6   r   rR   rS   ro   rp   rq   rP   rr   rs   r-   )r   rZ   r[   r(   rt   Úgemini_staterl   rv   s           r   Ú transform_retrieve_file_responsez;GoogleAIStudioFilesHandler.transform_retrieve_file_responseþ   s\  € ð!	KÜ× Ñ Ð!=¸|×?PÑ?PÔQØ#/×#4Ñ#4Ó#6ˆMÜ× Ñ Ð!4°mÔDà"/×"3Ñ"3°GÐ=PÓ"QˆLà˜xÒ'ØDO‘Ø Ò)Ø ‘à#�ä#Ø ×$Ñ$ U¨BÓ/Ü˜-×+Ñ+¨K¸Ó;Ó<ÜÜ—K‘KÜŸ™Ø)¨,Ñ7×?Ñ?ÀÀXÓNØ4óóóð '×*Ñ*¨=¸"Ó=ØØ#ØØGSÐW_ÒG_¤ M×$5Ñ$5°g¸rÓ$BÓ Côð ð fjôð øô" ò 	KÜ×$Ñ$Ð%OÐQRÔSÜÐEÀaÀSÐIÓJÐJûð	Kús   ‚DD  ÄD  Ä 	EÄ)$EÅEc                 óø   — | j                  |j                  d«      «      }|st        d«      ‚|j                  d«      xs | j                  «       }|st        d«      ‚| j	                  |«      }|› d|› �}i }||fS )aa  
        Transform delete file request for Google AI Studio.

        Args:
            file_id: The file URI (e.g., "files/abc123" or full URI)
            optional_params: Optional parameters
            litellm_params: LiteLLM parameters containing api_key

        Returns:
            tuple[str, dict]: (url, params) for the DELETE request
        r*   r2   r)   r3   rz   )r5   r6   r-   r,   r{   )	r   rx   r'   r(   r*   r)   Ú	file_namer9   Úparamss	            r   Útransform_delete_file_requestz8GoogleAIStudioFilesHandler.transform_delete_file_request*  s’   € ð" ×+Ñ+¨N×,>Ñ,>¸zÓ,JÓKˆÙÜÐ3Ó4Ð4ð (×+Ñ+¨IÓ6ÒL¸$×:JÑ:JÓ:LˆÙÜÐ2Ó3Ð3ð  ×9Ñ9¸'ÓBˆ	ð !�z ¨)¨Ð5ˆð !ˆà�Fˆ{Ðr   c                 óÊ  — 	 |j                   dk(  r‡d}t        |d«      rk|j                  r_t        |j                  j                  «      }d|v r<|j                  d«      d   j                  d«      d   }|j                  d«      sd|› �}t        |d	d
¬«      S t        d|j                  › �«      ‚# t        $ r)}t        j                  d|«       t        d|› �«      ‚d}~ww xY w)zª
        Transform Gemini's file delete response into OpenAI-style FileDeleted.

        Google AI Studio returns an empty JSON object {} on successful deletion.
        éÈ   ÚdeletedÚrequestz/files/r�   ú?r   r€   TrC   )rg   rŸ   rj   zFailed to delete file: z&Error parsing file delete response: %sz$Error parsing file delete response: N)Ústatus_codeÚhasattrr    rP   r9   Úsplitrƒ   r   r-   r–   rr   r   rs   )r   rZ   r[   r(   rx   r9   rv   s          r   Útransform_delete_file_responsez9GoogleAIStudioFilesHandler.transform_delete_file_responseO  sç   € ð	Ià×'Ñ'¨3Ò.à#�Ü˜<¨Ô3¸×8LÒ8LÜ!$ \×%9Ñ%9×%=Ñ%=Ó!>�CØ  CÑ'Ø"%§)¡)¨IÓ"6°rÑ":×"@Ñ"@ÀÓ"EÀaÑ"H˜à&×1Ñ1°(Ô;Ø(.¨w¨iÐ&8˜Gä" g°tÀFÔKÐKä Ð#:¸<×;LÑ;LÐ:MÐ!NÓOÐOøÜò 	IÜ×$Ñ$Ð%MÈqÔQÜÐCÀAÀ3ÐGÓHÐHûð	Iús   ‚BB0 ÂB0 Â0	C"Â9$CÃC"rk   c                 ó   — t        d«      ‚©Nz8GoogleAIStudioFilesHandler does not support file listing©ÚNotImplementedError)r   rk   r'   r(   s       r   Útransform_list_files_requestz7GoogleAIStudioFilesHandler.transform_list_files_requestn  ó   € ô "Ð"\Ó]Ð]r   c                 ó   — t        d«      ‚r§   r¨   ©r   rZ   r[   r(   s       r   Útransform_list_files_responsez8GoogleAIStudioFilesHandler.transform_list_files_responsev  r«   r   c                 ó   — t        d«      ‚©NzBGoogleAIStudioFilesHandler does not support file content retrievalr¨   )r   Úfile_content_requestr'   r(   s       r   Útransform_file_content_requestz9GoogleAIStudioFilesHandler.transform_file_content_request~  ó   € ô "Ð"fÓgÐgr   c                 ó   — t        d«      ‚r°   r¨   r­   s       r   Útransform_file_content_responsez:GoogleAIStudioFilesHandler.transform_file_content_response†  r³   r   )NNr   )%Ú__name__Ú
__module__Ú__qualname__r   Úpropertyr   r#   Údictr   rP   Úlistr   r/   Úboolr:   r   r<   r@   r   rY   ÚhttpxÚResponser   r   rw   Útupler~   r{   r˜   rœ   r   r¥   rª   r®   r²   r   rµ   r   r   r   r   r   "   sŽ  „ òð ð# \ò #ó ð#ð #Ø#ñà�c˜3�h‘ðð ðð Ð'Ñ(ð	ð
 ˜c 3˜h™ðð ˜S #˜X™ðð �t‘ðð ˜‘*ðð 
ˆc�3ˆh‰óð8 #ñà˜‘*ðð �t‘ðð ð	ð
 ðð ðð �t‘ðð 
óð:°ð ¸Ð>cÑ9dó ðà ðð ðð ð	ð
 ðð 
óð2
àð2
ð ,ð2
ð ð	2
ð
 ð2
ð 
ó2
ðh$Ià�T‰zð$Ið —n‘nð$Ið 'ð	$Ið
 ð$Ið 
ó$IðLàðð ðð ð	ð
 
ˆs�DˆyÑ	óð@*°ð *¸ó *ð8*Kà—n‘nð*Kð 'ð*Kð ð	*Kð
 
ó*KðX#àð#ð ð#ð ð	#ð
 
ˆs�DˆyÑ	ó#ðJIà—n‘nðIð 'ðIð ð	Ið
 
óIð>^à�t‘ð^ð ð^ð ð	^ð
 
ˆs�DˆyÑ	ó^ð^à—n‘nð^ð 'ð^ð ð	^ð
 
ÐÑ	ó^ðhð ðhð ð	hð
 
ˆs�DˆyÑ	óhðhà—n‘nðhð 'ðhð ð	hð
 
$ôhr   r   )!Ú__doc__rS   Útypingr   r   r   Úurllib.parser   r½   Úopenai.types.file_deletedr   Úlitellm._loggingr   Ú8litellm.litellm_core_utils.prompt_templates.common_utilsr	   Ú$litellm.litellm_core_utils.url_utilsr
   Ú*litellm.llms.base_llm.files.transformationr   r   Úlitellm.types.llms.geminir   Úlitellm.types.llms.openair   r   r   r   r   Úlitellm.types.utilsr   Úcommon_utilsr   r   r   r   r   ú<module>rÌ      sV   ðñó ß &Ñ &Ý !ã Ý 1å +Ý VÝ H÷õ F÷õ õ -å *ôjh °/õ jhr   