o
    ưi                     @   s  d dl Z d dlZd dlZd dlmZmZmZmZmZ d dl	m
Z
 d dlZd dlmZ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T d d	lmZmZmZ d d
lmZ d dlmZm Z  d dl!m"Z" e Z#e#j$deegdgde#j$deegdgde#j$deegdgdeefdededefddZ%e#j$deegdgdeefdededefddZ&e#j'deegdgde#j'deegdgde#j'deegdgdeefde(dededefddZ)e#j*deegdgde#j*deegdgde#j*deegdgdeefde(dededefd d!Z+e#j'd"eegdgde#j'd#eegdgde#j'd$eegdgdeefde(dededefd%d&Z,e#j$d'eegdgde#j$d(eegdgde#j$d)eegdgdeefdededefd*d+Z-e#j$d,eegdgde#j$d-eegdgde#j$d.eegdgdeefde(dededefd/d0Z.e#/de#/dej0d1d2d3eefd4ed5e(fd6d7Z1dS )8    N)AnyAsyncIteratorDictOptionalcast)uuid4)	APIRouterDependsHTTPExceptionRequestResponse)	WebSocket)verbose_proxy_logger)ModifyResponseException)*)UserAPIKeyAuthuser_api_key_authuser_api_key_auth_websocket)ProxyBaseLLMRequestProcessing)ResponseAPIUsageResponsesAPIResponse)DeleteResponseResult/v1/responses	responses)dependenciestagsz
/responsesz/openai/v1/responsesrequestfastapi_responseuser_api_key_dictc           %         s  ddl m}m}m}m}m}m}m}	m}
m	}m
}m}m}m}m}m}m} || dI dH }ddlm} ||dd|||dd	||d
}|rddlm} ddlm} td|d  |||d}| }|j||dI dH }t|d:i d|d| d|d| d|d|d|d|d|	d|
d|d|d|d|d|d|d | |S t|d!}z|jd:i d| d|d|d"d#d|
d|d|d|	d|ddd|d|d|d|d|d |I dH }|dryt |t!ry|j"d$v rydd%l#m$} t%t&| |
'd&}|ry|ryzAt(|d'i p!i }|d(d} | s9t)d)|j* d* t+d+|j,|j*|d|j*d,|d-I dH  td.|j* d/|j*  W |W S  t+yx }! zt-d0t.|!  W Y d}!~!|W S d}!~!ww |W S  t/y }! zB|!j0}"|
j1||!|"d1I dH  |!j2}#t!d2t3  d,t4t55 |!j6p|dt%t7d3d4|#d5gigd6t8dddd7d8}$|$W  Y d}!~!S d}!~!w t+y }! z|j9|!||
|d9I dH d}!~!ww );as  
    Follows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses

    Supports background mode with polling_via_cache for partial response retrieval.
    When background=true and polling_via_cache is enabled, returns a polling_id immediately
    and streams the response in the background, updating Redis cache.

    ```bash
    # Normal request
    curl -X POST http://localhost:4000/v1/responses     -H "Content-Type: application/json"     -H "Authorization: Bearer sk-1234"     -d '{
        "model": "gpt-4o",
        "input": "Tell me about AI"
    }'

    # Background request with polling
    curl -X POST http://localhost:4000/v1/responses     -H "Content-Type: application/json"     -H "Authorization: Bearer sk-1234"     -d '{
        "model": "gpt-4o",
        "input": "Tell me about AI",
        "background": true
    }'
    ```
    r   )_read_request_bodygeneral_settings
llm_routernative_background_modepolling_cache_ttlpolling_via_cache_enabledproxy_configproxy_logging_objredis_usage_cacheselect_data_generatoruser_api_baseuser_max_tokens
user_modeluser_request_timeoutuser_temperatureversionr   N)should_use_polling_for_request
backgroundFmodel )Zbackground_moder$   redis_cacher2   r!   r"   )background_streaming_taskResponsePollingHandlerz4Starting background response with polling for model=)r4   ttl)
polling_idrequest_datar9   datapolling_handlerr   r   r   r    r!   r%   r&   r(   r+   r-   r,   r*   r)   r.   r;   
route_type
aresponses)ZqueuedZin_progress)_PROXY_LiteLLMManagedFilesZmanaged_filesZ_hidden_paramsmodel_idz9No model_id found in response hidden params for response z!, skipping managed object storagez+No model_id found in response hidden paramsresponse)Zunified_object_idZfile_objectZlitellm_parent_otel_spanZmodel_object_idZfile_purposer   zStored background response z* in managed objects table with unified_id=z>Failed to store background response in managed objects table: )r   Zoriginal_exceptionr:   Zresp_contenttext)typerD   	completed)Zinput_tokensZoutput_tokensZtotal_tokens)idobjectZ
created_atr2   outputstatususageer   r&   r.    ):litellm.proxy.proxy_serverr   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   .litellm.proxy.response_polling.polling_handlerr0   getZ3litellm.proxy.response_polling.background_streamingr5   r7   r   infoZgenerate_polling_idZcreate_initial_stateasynciocreate_taskcopyr   base_process_llm_request
isinstancer   rJ   Z,litellm_enterprise.proxy.hooks.managed_filesr@   r   r   Zget_proxy_hookgetattrwarningrG   	ExceptionZstore_unified_object_iderrorstrr   r:   Zpost_call_failure_hookmessager   inttimer2   r   r   _handle_llm_api_exception)%r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r;   r0   Zshould_use_pollingr5   r7   r<   r9   Zinitial_state	processorrB   r@   Zmanaged_files_objZhidden_paramsrA   rM   _dataZviolation_textZresponse_objrN   rN   e/home/app/Keep/.python/lib/python3.10/site-packages/litellm/proxy/response_api_endpoints/endpoints.pyresponses_api   sL  H0


	


	

	

rd   z/cursor/chat/completionsc                    s  ddl m ddlm ddlm}mm}m}m	}m
}m}m}	m}
m}m}m} ddlm  ddlm} ddlm} || dI d	H }d
|v rRd|vrR|d
|d< t|d} fdd}zj|jd$i d| d|d|ddd|d|d|d|d|dd	d|
d|d|d|	d|d|I d	H }t||r|jd }jj|jdd!|| tt ||j|jdg i i d	d	d	d"}|W S |W S  t!y } z|j"||||d#I d	H d	}~ww )%aa  
    Cursor-specific endpoint that accepts Responses API input format but returns chat completions format.
    
    This endpoint handles requests from Cursor IDE which sends Responses API format (`input` field)
    but expects chat completions format response (`choices`, `messages`, etc.).
    
    ```bash
    curl -X POST http://localhost:4000/cursor/chat/completions     -H "Content-Type: application/json"     -H "Authorization: Bearer sk-1234"     -d '{
        "model": "gpt-4o",
        "input": [{"role": "user", "content": "Hello"}]
    }'
    Responds back in chat completions format.
    ```
    r   )responses_api_bridge)CustomStreamWrapper)r   async_data_generatorr    r!   r%   r&   r)   r*   r+   r,   r-   r.   )!BaseResponsesAPIStreamingIterator)r   )ModelResponser/   Nmessagesinputr=   c                    sd   t |  r+jjttt | ddd}|d}||ddd|d}|||dS | ||dS )	at  
        Custom generator that transforms Responses API streaming chunks to chat completion chunks.
        
        This generator is used for the cursor endpoint to convert Responses API format responses
        to chat completion format that Cursor IDE expects.
        
        Args:
            response: The streaming response (BaseResponsesAPIStreamingIterator or other)
            user_api_key_dict: User API key authentication dict
            request_data: Request data containing model, logging_obj, etc.
        
        Returns:
            Async generator that yields SSE-formatted chat completion chunks
        F)Zstreaming_responseZsync_stream	json_modelitellm_logging_objr2   r3   N)completion_streamr2   Zcustom_llm_providerlogging_obj)rB   r   r:   )rW   transformation_handlerZget_model_response_iteratorr   r   r\   rQ   )rB   r   r:   rn   ro   Zstreamwrapperrh   rf   rg   re   rN   rc   cursor_data_generator<  s.   


z6cursor_chat_completions.<locals>.cursor_data_generatorr   r   r   r>   r?   r&   r!   r    r%   r(   r2   r+   r-   r,   r*   r)   r.   rm   r3   )r2   Zraw_responseZmodel_responsero   r:   rj   Zoptional_paramsZlitellm_paramsencodingZapi_keyrl   rL   rN   )#ZBlitellm.completion_extras.litellm_responses_transformation.handlerre   Z,litellm.litellm_core_utils.streaming_handlerrf   rO   r   rg   r    r!   r%   r&   r)   r*   r+   r,   r-   r.   Z$litellm.responses.streaming_iteratorrh   litellm.types.llms.openair   Zlitellm.types.utilsri   popr   rV   rW   r;   rQ   rp   Ztransform_responser   r   rZ   r`   )r   r   r   r   r    r!   r%   r&   r)   r*   r+   r,   r-   r.   r   ri   r;   ra   rr   rB   ro   Ztransformed_responserM   rN   rq   rc   cursor_chat_completions  s   8
-
	


rv   z/v1/responses/{response_id}z/responses/{response_id}z"/openai/v1/responses/{response_id}response_idc              
      sb  ddl m}m}m}m}m}m}	m}
m}m	}m
}m}m}m} ddlm} || rM|	s2tddd||	d}|| I dH }|sKtd	d
|  dd|S ||dI dH }| |d< t|d}z:|jd!i d|d|d|ddd|d|d|d|d|
ddd|d|d|d|d|d|I dH W S  ty } z|j||||d I dH d}~ww )"ai  
    Get a response by ID.
    
    Supports both:
    - Polling IDs (litellm_poll_*): Returns cumulative cached content from background responses
    - Provider response IDs: Passes through to provider API
    
    Follows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/get
    
    ```bash
    # Get polling response
    curl -X GET http://localhost:4000/v1/responses/litellm_poll_abc123     -H "Authorization: Bearer sk-1234"
    
    # Get provider response
    curl -X GET http://localhost:4000/v1/responses/resp_abc123     -H "Authorization: Bearer sk-1234"
    ```
    r   r   r    r!   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r6     z3Redis cache not configured. Polling requires Redis.status_codedetailr4   N  Polling response z not found or expiredr/   rw   r=   r   r   r   r>   Zaget_responsesr&   r!   r    r%   r(   r2   r+   r-   r,   r*   r)   r.   rL   rN   )rO   r   r    r!   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   rP   r7   is_polling_idr
   	get_stater   rV   rZ   r`   )rw   r   r   r   r   r    r!   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r7   r<   stater;   ra   rM   rN   rN   rc   get_response  s~   <(




	
r   c              
      s  ddl m}m}m}m}m}m}	m}
m}m	}m
}m}m}m} ddlm} || rb|	s2tddd||	d}|| I dH }|sKtd	d
|  dd|| I dH }|r\t| dddS tddd||dI dH }| |d< t|d}z:|jd%i d|d|d|ddd|d|d|d|d|
ddd|d|d |d!|d"|d#|I dH W S  ty } z|j||||d$I dH d}~ww )&a  
    Delete a response by ID.
    
    Supports both:
    - Polling IDs (litellm_poll_*): Deletes from Redis cache
    - Provider response IDs: Passes through to provider API
    
    Follows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/delete
    
    ```bash
    curl -X DELETE http://localhost:4000/v1/responses/resp_abc123     -H "Authorization: Bearer sk-1234"
    ```
    r   rx   r6   ry   Redis cache not configured.rz   r}   Nr~   r   
 not foundrB   T)rG   rH   Zdeletedz!Failed to delete polling responser/   rw   r=   r   r   r   r>   Zadelete_responsesr&   r!   r    r%   r(   r2   r+   r-   r,   r*   r)   r.   rL   rN   )rO   r   r    r!   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   rP   r7   r   r
   r   Zdelete_pollingr   r   rV   rZ   r`   )rw   r   r   r   r   r    r!   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r7   r<   r   successr;   ra   rM   rN   rN   rc   delete_response  s   <#




	
r   z'/v1/responses/{response_id}/input_itemsz$/responses/{response_id}/input_itemsz./openai/v1/responses/{response_id}/input_itemsc              
      s  ddl m}m}m}m}m}m}	m}
m}m	}m
}m}m} ||dI dH }| |d< t|d}z:|jdi d|d|d	|d
dd|d|d|d|d|	ddd|d|d|d|d|
d|I dH W S  ty } z|j||||dI dH d}~ww )z List input items for a response.r   r   r    r!   r%   r&   r(   r)   r*   r+   r,   r-   r.   r/   Nrw   r=   r   r   r   r>   Zalist_input_itemsr&   r!   r    r%   r(   r2   r+   r-   r,   r*   r)   r.   rL   rN   rO   r   r    r!   r%   r&   r(   r)   r*   r+   r,   r-   r.   r   rV   rZ   r`   )rw   r   r   r   r   r    r!   r%   r&   r(   r)   r*   r+   r,   r-   r.   r;   ra   rM   rN   rN   rc   get_response_input_items  s`   8

	
r   z/v1/responses/compactz/responses/compactz/openai/v1/responses/compactc              
      s   ddl m}m}m}m}m}m}m}	m}
m	}m
}m}m} || dI dH }t|d}z:|jdi d| d|d|d	d
d|d|d|d|d|ddd|d|d|d|
d|	d|I dH W S  ty| } z|j||||dI dH d}~ww )a  
    Compact a response by running a compaction pass over a conversation.
    
    Returns encrypted, opaque items that can be used to reduce context size.
    
    Follows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/compact
    
    ```bash
    curl -X POST http://localhost:4000/v1/responses/compact     -H "Content-Type: application/json"     -H "Authorization: Bearer sk-1234"     -d '{
        "model": "gpt-4o",
        "input": [{"role": "user", "content": "Hello"}]
    }'
    ```
    r   r   r/   Nr=   r   r   r   r>   Zacompact_responsesr&   r!   r    r%   r(   r2   r+   r-   r,   r*   r)   r.   rL   rN   r   )r   r   r   r   r    r!   r%   r&   r(   r)   r*   r+   r,   r-   r.   r;   ra   rM   rN   rN   rc   compact_response  s^   8%

	
r   z"/v1/responses/{response_id}/cancelz/responses/{response_id}/cancelz)/openai/v1/responses/{response_id}/cancelc              
      s  ddl m}m}m}m}m}m}	m}
m}m	}m
}m}m}m} ddlm} || re|	s2tddd||	d}|| I dH }|sKtd	d
|  dd|| I dH }|r_|| I dH }|S tddd||dI dH }| |d< t|d}z:|jd"i d|d|d|ddd|d|d|d|d|
ddd|d|d|d|d|d |I dH W S  ty } z|j||||d!I dH d}~ww )#a  
    Cancel a response by ID.
    
    Supports both:
    - Polling IDs (litellm_poll_*): Cancels background response and updates status in Redis
    - Provider response IDs: Passes through to provider API
    
    Follows the OpenAI Responses API spec: https://platform.openai.com/docs/api-reference/responses/cancel
    
    ```bash
    # Cancel polling response
    curl -X POST http://localhost:4000/v1/responses/litellm_poll_abc123/cancel     -H "Authorization: Bearer sk-1234"
    
    # Cancel provider response
    curl -X POST http://localhost:4000/v1/responses/resp_abc123/cancel     -H "Authorization: Bearer sk-1234"
    ```
    r   rx   r6   ry   r   rz   r}   Nr~   r   r   z!Failed to cancel polling responser/   rw   r=   r   r   r   r>   Zacancel_responsesr&   r!   r    r%   r(   r2   r+   r-   r,   r*   r)   r.   rL   rN   )rO   r   r    r!   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   rP   r7   r   r
   r   Zcancel_pollingr   rV   rZ   r`   )rw   r   r   r   r   r    r!   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r7   r<   r   r   Zupdated_stater;   ra   rM   rN   rN   rc   cancel_response  s   <(




	
r   .z5The model to use for the responses WebSocket session.)description	websocketr2   c                    s  ddl m}m}m}m}m}m}m}	m}
m	}m
} ddlm} dd | jdp)ddD }i }|r9|d |d	< | jd#i |I d
H   | d}t| jdpQg }ddd|d}t|d}| j|_ fdd}||_t|d}z|j|||||||	||
|| ddI d
H \}}W nA ty } z5td z| tddt|ddI d
H  W n	 ty   Y nw | j dddI d
H  W Y d
}~d
S d
}~ww z||d< ||d||	d I d
H }|I d
H  W d
S  ty   td! | j dd"dI d
H  Y d
S w )$a  
    Responses API WebSocket mode endpoint.

    Keeps a persistent WebSocket connection for response.create events,
    enabling lower-latency agentic workflows with many tool-call round trips.

    See: https://developers.openai.com/api/docs/guides/websocket-mode/
    r   )
r    r!   r%   r&   r)   r*   r+   r,   r-   r.   )route_requestc                 S   s   g | ]
}|  r|  qS rN   )strip).0prN   rN   rc   
<listcomp>  s    z0responses_websocket_endpoint.<locals>.<listcomp>zsec-websocket-protocolr3   ,ZsubprotocolN)r2   r   headershttpPOSTr   )rE   methodpathr   )scopec                      s   d  d  S )Nz{"model": "z"})encoderN   r2   rN   rc   return_body  s   z1responses_websocket_endpoint.<locals>.return_bodyr=   Z_aresponses_websocket)r   r    r   r.   r&   r%   r+   r-   r,   r*   r)   r2   r>   z"Responses WebSocket pre-call errorr[   Zpre_call_error)rE   r]   )rE   r[   i  zPre-call error)codereasonr   )r;   r>   r!   r+   zResponses WebSocket errorzInternal server errorrN   )!rO   r    r!   r%   r&   r)   r*   r+   r,   r-   r.   Zlitellm.proxy.route_llm_requestr   r   rQ   splitacceptlistr   r   url_urlbodyr   Z common_processing_pre_call_logicrZ   r   	exceptionZ	send_textjsondumpsr\   close)r   r2   r   r    r!   r%   r&   r)   r*   r+   r,   r-   r.   r   Zrequested_protocolsZaccept_kwargsr;   Zheaders_listr   r   r   Zbase_llm_response_processorrm   rM   Zllm_callrN   r   rc   responses_websocket_endpoint  s   0




r   )2rS   r   r_   typingr   r   r   r   r   uuidr   Zfastapir   r	   r
   r   r   Zstarlette.websocketsr   Zlitellm._loggingr   Z%litellm.integrations.custom_guardrailr   Zlitellm.proxy._typesZ$litellm.proxy.auth.user_api_key_authr   r   r   Z'litellm.proxy.common_request_processingr   rt   r   r   Zlitellm.types.responses.mainr   Zrouterpostrd   rv   rQ   r\   r   deleter   r   r   r   r   ZQueryr   rN   rN   rN   rc   <module>   sx    Z 	b	h	5C	m