o
    ưia1                  	   @   s   d Z ddlZddlmZmZ ddlmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZmZ G d	d
 d
Z	ddededeee  defddZdS )z>
Response Polling Handler for Background Responses with Cache
    N)datetimetimezone)AnyDictListOptional)verbose_proxy_logger)uuid4)
RedisCache)ResponsesAPIResponseResponsesAPIStatusc                +   @   s  e Zd ZdZdZdZd1dee defdd	Z	e
d
efddZe
ded
efddZe
ded
efddZdedeeef d
efddZ																			d2dedee dee dee dee dee dee dee dee dee dee d ee d!ee d"ee d#ee d$ee d%ee d&ee d'ee d(ee d
df*d)d*Zded
eeeef  fd+d,Zded
efd-d.Zded
efd/d0ZdS )3ResponsePollingHandlerz0Handles polling-based responses with Redis cachezlitellm:polling:response:Zlitellm_poll_N  redis_cachettlc                 C   s   || _ || _d S N)r   r   )selfr   r    r   e/home/app/Keep/.python/lib/python3.10/site-packages/litellm/proxy/response_polling/polling_handler.py__init__   s   
zResponsePollingHandler.__init__returnc                 C   s   | j  t  S )z4Generate a unique UUID for polling with clear prefix)POLLING_ID_PREFIXr	   )clsr   r   r   generate_polling_id   s   z*ResponsePollingHandler.generate_polling_idresponse_idc                 C   s   | | jS )z&Check if a response_id is a polling ID)
startswithr   )r   r   r   r   r   is_polling_id   s   z$ResponsePollingHandler.is_polling_id
polling_idc                 C   s   | j  | S )z$Get Redis cache key for a polling ID)CACHE_KEY_PREFIX)r   r   r   r   r   get_cache_key"   s   z$ResponsePollingHandler.get_cache_keyrequest_datac              
      s   t ttj }t|dd|g |di dd}| |}| j	r>| j	j
|| | jdI dH  td| d| j d	 |S )
a  
        Create initial state in Redis for a polling request
        
        Uses OpenAI ResponsesAPIResponse object:
        https://platform.openai.com/docs/api-reference/responses/object
        
        Args:
            polling_id: Unique identifier for this polling request
            request_data: Original request data
        
        Returns:
            ResponsesAPIResponse object following OpenAI spec
        responseZqueuedmetadataN)idobjectstatusZ
created_atoutputr"   usagekeyvaluer   z"Created initial polling state for z
 with TTL=s)intr   nowr   utc	timestampr   getr   r   async_set_cacheZmodel_dump_jsonr   r   debug)r   r   r    Zcreated_timestampr!   	cache_keyr   r   r   create_initial_state'   s,   


z+ResponsePollingHandler.create_initial_stater%   r'   errorincomplete_details	reasoningtool_choicetoolsr&   modelinstructionstemperaturetop_pmax_output_tokensprevious_response_idtext
truncationparallel_tool_callsuserstorec                    s  | j sdS | |}| j |I dH }|s td|  dS t|}|r+||d< |	dur3|	|d< |r9||d< |rCd|d< ||d< |rI||d< |durQ||d	< |durY||d
< |dura||d< |
duri|
|d< |durq||d< |dury||d< |dur||d< |dur||d< |dur||d< |dur||d< |dur||d< |dur||d< |dur||d< |dur||d< | j j|t|| j	dI dH  t
|dg }td| d|d  d|  dS )a#  
        Update the polling state in Redis
        
        Uses OpenAI Response object format with native status types:
        https://platform.openai.com/docs/api-reference/responses/object
        
        Args:
            polling_id: Unique identifier for this polling request
            status: OpenAI ResponsesAPIStatus value
            usage: Usage information
            error: Error dict (automatically sets status to "failed")
            incomplete_details: Details for incomplete responses
            reasoning: Reasoning configuration from response.completed
            tool_choice: Tool choice configuration from response.completed
            tools: Tools list from response.completed
            output: Full output list to replace current output
            model: Model identifier
            instructions: System instructions
            temperature: Sampling temperature
            top_p: Nucleus sampling parameter
            max_output_tokens: Maximum output tokens
            previous_response_id: ID of previous response in conversation
            text: Text configuration
            truncation: Truncation setting
            parallel_tool_calls: Whether parallel tool calls are enabled
            user: User identifier
            store: Whether to store the response
        Nz&No cached state found for polling_id: r%   r&   r'   failedr5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   r(   zUpdated polling state for z	: status=z, output_items=)r   r   async_get_cacher   warningjsonloadsr1   dumpsr   lenr0   r2   )r   r   r%   r'   r5   r6   r7   r8   r9   r&   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   r3   cached_statestateZoutput_countr   r   r   update_stateU   sv   4

z#ResponsePollingHandler.update_statec                    s:   | j sdS | |}| j |I dH }|rt|S dS )z$Get current polling state from RedisN)r   r   rF   rH   rI   )r   r   r3   rL   r   r   r   	get_state   s   

z ResponsePollingHandler.get_statec                    s   | j |ddI dH  dS )zx
        Cancel a polling request
        
        Following OpenAI Response object format for cancelled status
        	cancelled)r   r%   NT)rN   )r   r   r   r   r   cancel_polling   s   z%ResponsePollingHandler.cancel_pollingc                    s,   | j sdS | |}| j |I dH  dS )z#Delete a polling request from cacheFNT)r   r   Zasync_delete_cache)r   r   r3   r   r   r   delete_polling   s   
z%ResponsePollingHandler.delete_polling)Nr   )NNNNNNNNNNNNNNNNNNN)__name__
__module____qualname____doc__r   r   r   r
   r,   r   classmethodstrr   boolr   r   r   r   r   r4   r   listfloatrN   rO   rQ   rR   r   r   r   r   r      s    

1	

 r   background_moder:   native_background_moder   c              
   C   sF  | r|r|sdS |r||v rt d| d dS |dkrdS t|trd|v r7|dd }||v r5dS dS |durzG|j|g }|D ]:}|j| }	|	d	i }
|
d
}|sj|
dd}d|v rj|dd }|r||v rt d| d|   W dS qEW dS  ty } zt d| d|  W Y d}~dS d}~ww dS )a  
    Determine if polling via cache should be used for a request.
    
    Args:
        background_mode: Whether background=true was set in the request
        polling_via_cache_enabled: Config value - False, "all", or list of providers
        redis_cache: Redis cache instance (required for polling)
        model: Model name from the request (e.g., "gpt-5" or "openai/gpt-4o")
        llm_router: LiteLLM router instance for looking up model deployments
        native_background_mode: List of model names that should use native provider 
            background mode instead of polling via cache
    
    Returns:
        True if polling should be used, False otherwise
    FzModel z> is in native_background_mode list, skipping polling via cacheallT/r   Nlitellm_paramsZcustom_llm_providerr:    zPolling enabled for model=z, provider=z%Could not resolve provider for model z: )	r   r2   
isinstancerZ   splitZ model_name_to_deployment_indicesr0   Z
model_list	Exception)r\   Zpolling_via_cache_enabledr   r:   Z
llm_routerr]   providerindicesidxZdeployment_dictr`   Zdep_providerZ	dep_modeler   r   r   should_use_polling_for_request   sT   



ri   r   )rV   rH   r   r   typingr   r   r   r   Zlitellm._loggingr   Zlitellm._uuidr	   Zlitellm.caching.redis_cacher
   Zlitellm.types.llms.openair   r   r   rY   rX   ri   r   r   r   r   <module>   s(     w
