o
    ưiXE                     @   s  d dl 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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Zd d	lmZmZmZmZ d d
lmZ d dlm Z  erod dl!m"Z# ddl$m%Z& e#Z'e&Z%neZ'eZ%dee(e(f fddZ)G dd de Z*dS )    )TYPE_CHECKINGAnyDictOptionalTupleUnionN)RequestFiles) VideoCreateOptionalRequestParamsVideoObject)GenericLiteLLMParams)get_secret_str)encode_video_id_with_providerextract_original_video_id)ImageEditRequestUtils)"GeminiLongRunningOperationResponseGeminiVideoGenerationInstanceGeminiVideoGenerationParametersGeminiVideoGenerationRequest)%DEFAULT_GOOGLE_VIDEO_DURATION_SECONDS)BaseVideoConfig)Logging   )BaseLLMExceptionreturnc                 C   s@   t | }t| dr| d |  }t|d}||dS )z
    Convert image file to Gemini format with base64 encoding and MIME type.
    
    Args:
        image_file: File-like object opened in binary mode (e.g., open("path", "rb"))
    
    Returns:
        Dict with bytesBase64Encoded and mimeType
    seekr   zutf-8)ZbytesBase64EncodedZmimeType)r   Zget_image_content_typehasattrr   readbase64	b64encodedecode)Z
image_fileZ	mime_typeZimage_bytesZbase64_encoded r    `/home/app/Keep/.python/lib/python3.10/site-packages/litellm/llms/gemini/videos/transformation.py_convert_image_to_gemini_format   s   



r"   c                       s  e Zd ZdZ fddZdedefddZdeded	e	de
eef fd
dZdedee fddZ		dAdededee dee def
ddZdedee dedefddZdededede
dededee
eef fddZ		dAdedejdedee dee
 defd d!Zd"ededededeee
f f
d#d$Z	dBdejdedee defd%d&Z	dBd"edededed'ee deee
f fd(d)Zdejdedefd*d+Z	dBd"ededededed,ee
eef  deee
f fd-d.Z 	dBdejdedee defd/d0Z!				dCdededed1ee d2ee" d3ee d4ee
eef  deee
f fd5d6Z#	dBdejdedee de
eef fd7d8Z$d"ededededeee
f f
d9d:Z%dejdedefd;d<Z&d=ed>e"de'eej(f de)fd?d@Z*  Z+S )DGeminiVideoConfiga  
    Configuration class for Gemini (Veo) video generation.
    
    Veo uses a long-running operation model:
    1. POST to :predictLongRunning returns operation name
    2. Poll operation until done=true
    3. Extract video URI from response
    4. Download video using file API
    c                    s   t    d S N)super__init__)self	__class__r    r!   r&   A   s   zGeminiVideoConfig.__init__modelr   c                 C   s   g dS )z
        Get the list of supported OpenAI parameters for Veo video generation.
        Veo supports minimal parameters compared to OpenAI.
        )r*   promptinput_referencesecondssizer    )r'   r*   r    r    r!   get_supported_openai_paramsD   s   z-GeminiVideoConfig.get_supported_openai_paramsvideo_create_optional_paramsdrop_paramsc              	   C   s   i }|  |}dd |D }d|v r|d |d< d|v r/|d }|dur/| |}|r/||d< d|v rX|d }	zt|	trAt|	n|	}
|
durK|
|d	< W n ttfyW   Y nw | D ]\}}||vrl||vrl|||< q\|S )
u  
        Map OpenAI-style parameters to Veo format.
        
        Mappings:
        - prompt → prompt
        - input_reference → image
        - size → aspectRatio (e.g., "1280x720" → "16:9")
        - seconds → durationSeconds (defaults to 4 seconds if not provided)
        
        All other params are passed through as-is to support Gemini-specific parameters.
        c                 S   s   h | ]}|d vr|qS )>   r+   r*   r    ).0paramr    r    r!   	<setcomp>f   s
    z6GeminiVideoConfig.map_openai_params.<locals>.<setcomp>r,   imager.   NZaspectRatior-   durationSeconds)r/   _convert_size_to_aspect_ratio
isinstancestrint
ValueError	TypeErroritems)r'   r0   r*   r1   Zmapped_paramsZsupported_openai_paramsZopenai_params_to_mapr.   Zaspect_ratior-   durationkeyvaluer    r    r!   map_openai_paramsQ   s8   

z#GeminiVideoConfig.map_openai_paramsr.   c                 C   s"   |sdS ddddd}| |dS )z
        Convert OpenAI size format to Veo aspectRatio format.
        
        https://cloud.google.com/vertex-ai/generative-ai/docs/image/generate-videos
        
        Supported aspect ratios: 9:16 (portrait), 16:9 (landscape)
        Nz16:9z9:16)Z1280x720Z	1920x1080Z720x1280Z	1080x1920)get)r'   r.   Zaspect_ratio_mapr    r    r!   r7      s   z/GeminiVideoConfig._convert_size_to_aspect_ratioNheadersapi_keylitellm_paramsc                 C   sN   |r
|j r
|p	|j }|ptj ptdptd}|std||dd |S )z
        Validate environment and add Gemini API key to headers.
        Gemini uses x-goog-api-key header for authentication.
        ZGOOGLE_API_KEYZGEMINI_API_KEYzGEMINI_API_KEY or GOOGLE_API_KEY is required for Veo video generation. Set it via environment variable or pass it as api_key parameter.zapplication/json)zx-goog-api-keyzContent-Type)rD   litellmr   r;   update)r'   rC   r*   rD   rE   r    r    r!   validate_environment   s$   

z&GeminiVideoConfig.validate_environmentapi_basec                 C   sP   |du r
t dp	d}|r|dkr|dS |dd}|d d| d}|S )	z
        Get the complete URL for Veo video generation.
        For video creation: returns full URL with :predictLongRunning
        For status/delete: returns base URL only
        NZGEMINI_API_BASEz)https://generativelanguage.googleapis.com /zgemini/z/v1beta/models/z:predictLongRunning)r   rstripreplace)r'   r*   rI   rE   Z
model_nameurlr    r    r!   get_complete_url   s   
z"GeminiVideoConfig.get_complete_urlr+   $video_create_optional_request_paramsc                 C   sl   t |d}| }d|v r|d durt|d }	|	|d< tdi |}
t|g|
d}|jdd}|g |fS )a  
        Transform the video creation request for Veo API.
        
        Veo expects:
        {
            "instances": [
                {
                    "prompt": "A cat playing with a ball of yarn"
                }
            ],
            "parameters": {
                "aspectRatio": "16:9",
                "durationSeconds": 8,
                "resolution": "720p"
            }
        }
        )r+   r5   N)Z	instances
parametersT)Zexclude_noner    )r   copyr"   r   r   Z
model_dump)r'   r*   r+   rI   rP   rE   rC   instanceZparams_copyZ
image_datarQ   Zrequest_body_objrequest_datar    r    r!   transform_video_create_request   s   

z0GeminiVideoConfig.transform_video_create_requestraw_responselogging_objcustom_llm_providerrT   c              
   C   s   |  }z	td
i |}W n ty  } ztd| d}~ww |j}	|	s-td| |r6t|	||}
n|	}
t|
dd|d}i }|ri|di }|dpPt}|durizt	||d	< W n tt
fyh   Y nw ||_|S )a  
        Transform the Veo video creation response.
        
        Veo returns:
        {
            "name": "operations/generate_1234567890",
            "metadata": {...},
            "done": false,
            "error": {...}
        }
        
        We return this as a VideoObject with:
        - id: operation name (used for polling)
        - status: "processing"
        - usage: includes duration_seconds for cost calculation
        z$Failed to parse operation response: Nz#No operation name in Veo response: video
processing)idobjectstatusr*   rQ   r6   Zduration_secondsr    )jsonr   	Exceptionr;   namer   r
   rB   r   floatr<   usage)r'   r*   rV   rW   rX   rT   response_dataoperation_responseeoperation_namevideo_id	video_objZ
usage_datarQ   r>   r    r    r!   transform_video_create_response  s>   z1GeminiVideoConfig.transform_video_create_responserg   c                 C   s(   t |}|d d| }i }||fS )z
        Transform the video status retrieve request for Veo API.
        
        Veo polls operations at:
        GET https://generativelanguage.googleapis.com/v1beta/{operation_name}
        rK   /v1beta/)r   rL   )r'   rg   rI   rE   rC   rf   rN   paramsr    r    r!   'transform_video_status_retrieve_request@  s   z9GeminiVideoConfig.transform_video_status_retrieve_requestc           
      C   sR   |  }tdi |}|j}|j}|rt||d}n|}t|d|s#dndd}	|	S )a  
        Transform the Veo operation status response.
        
        Veo returns:
        {
            "name": "operations/generate_1234567890",
            "done": false  # or true when complete
        }
        
        When done=true:
        {
            "name": "operations/generate_1234567890",
            "done": true,
            "response": {
                "generateVideoResponse": {
                    "generatedSamples": [
                        {
                            "video": {
                                "uri": "files/abc123..."
                            }
                        }
                    ]
                }
            }
        }
        NrY   rZ   	completed)r[   r\   r]   r    )r^   r   r`   doner   r
   )
r'   rV   rW   rX   rc   rd   rf   Zis_donerg   rh   r    r    r!   (transform_video_status_retrieve_responseS  s    
z:GeminiVideoConfig.transform_video_status_retrieve_responsevariantc                 C   s   t |}|d d| }tj}|j||d}	|	  |	 }
tdi |
}|js.t	d|j
s5t	d|j
jj}|d jj}i }||fS )	z
        Transform the video content request for Veo API.

        For Veo, we need to:
        1. Get operation status to extract video URI
        2. Return download URL for the video
        rK   rj   )rN   rC   zaVideo generation is not complete yet. Please check status with video_status() before downloading.z'No response data in completed operationr   Nr    )r   rL   rF   Zmodule_level_clientrB   raise_for_statusr^   r   rn   r;   responseZgenerateVideoResponseZgeneratedSamplesrY   uri)r'   rg   rI   rE   rC   rp   rf   Z
status_urlclientZstatus_responserc   rd   Zgenerated_samplesZdownload_urlrk   r    r    r!   transform_video_content_request  s"   
z1GeminiVideoConfig.transform_video_content_requestc                 C   s   |j S )zn
        Transform the Veo video content download response.
        Returns the video bytes directly.
        )contentr'   rV   rW   r    r    r!    transform_video_content_response  s   	z2GeminiVideoConfig.transform_video_content_response
extra_bodyc                 C      t d)z:
        Video remix is not supported by Veo API.
        z_Video remix is not supported by Google Veo. Please use video_generation() to create new videos.NotImplementedError)r'   rg   r+   rI   rE   rC   ry   r    r    r!   transform_video_remix_request  s   z/GeminiVideoConfig.transform_video_remix_requestc                 C   rz   )zVideo remix is not supported.z+Video remix is not supported by Google Veo.r{   r'   rV   rW   rX   r    r    r!   transform_video_remix_response     z0GeminiVideoConfig.transform_video_remix_responseafterlimitorderextra_queryc                 C   rz   )z9
        Video list is not supported by Veo API.
        zoVideo list is not supported by Google Veo. Use the operations endpoint directly if you need to list operations.r{   )r'   rI   rE   rC   r   r   r   r   r    r    r!   transform_video_list_request  s   z.GeminiVideoConfig.transform_video_list_requestc                 C   rz   )zVideo list is not supported.z*Video list is not supported by Google Veo.r{   r~   r    r    r!   transform_video_list_response  r   z/GeminiVideoConfig.transform_video_list_responsec                 C   rz   )z;
        Video delete is not supported by Veo API.
        z[Video delete is not supported by Google Veo. Videos are automatically cleaned up by Google.r{   )r'   rg   rI   rE   rC   r    r    r!   transform_video_delete_request  s   
z0GeminiVideoConfig.transform_video_delete_requestc                 C   rz   )zVideo delete is not supported.z,Video delete is not supported by Google Veo.r{   rw   r    r    r!   transform_video_delete_response  s   z1GeminiVideoConfig.transform_video_delete_responseerror_messagestatus_codec                 C   s   ddl m} ||||dS )N   )GeminiError)r   messagerC   )Zcommon_utilsr   )r'   r   r   rC   r   r    r    r!   get_error_class  s   z!GeminiVideoConfig.get_error_class)NNr$   )NNNN),__name__
__module____qualname____doc__r&   r9   listr/   r	   boolr   r   rA   r   r7   dictr   rH   rO   r   r   rU   httpxResponseLiteLLMLoggingObjr
   ri   rl   ro   ru   bytesrx   r}   r   r:   r   r   r   r   r   ZHeadersr   r   __classcell__r    r    r(   r!   r#   6   s   


8
"

2
=


9

)




	


	


r#   )+typingr   r   r   r   r   r   r   r   Zhttpx._typesr   Zlitellm.types.videos.mainr	   r
   Zlitellm.types.routerr   Zlitellm.secret_managers.mainr   Zlitellm.types.videos.utilsr   r   Zlitellm.images.utilsr   rF   Zlitellm.types.llms.geminir   r   r   r   Zlitellm.constantsr   Z+litellm.llms.base_llm.videos.transformationr   Z*litellm.litellm_core_utils.litellm_loggingr   Z_LiteLLMLoggingObjZbase_llm.chat.transformationr   Z_BaseLLMExceptionr   r9   r"   r#   r    r    r    r!   <module>   s,     