
    jhJ                         d dl mZmZmZmZmZmZmZ d dlZd dl	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 d d	l d d
lmZ d dlmZ d dlmZ ddlmZ er	d dl m!Z" e"Z#neZ# G d de      Z$y)    )TYPE_CHECKINGAnyDictOptionalUnioncastget_type_hintsN)ResponseReasoningItem)	BaseModel)verbose_logger)_safe_convert_created_field)BaseResponsesAPIConfig)get_secret_str)*)GenericLiteLLMParams)LlmProviders)process_response_headers   )OpenAIError)Loggingc                      e Zd Zedefd       ZdedefdZde	dede
defdZdedeeef   d	ed
ededefdZdeeef   deeef   fdZdeeef   deeef   fdZdedej,                  dedefdZdeded
ee   defdZdee   d
edefdZdedededefdZededefd       Z 	 d-dee   dee
   dee   de
fdZ!deded
edede"eef   f
dZ#dej,                  dede$fd Z%deded
edede"eef   f
d!Z&dej,                  dedefd"Z'	 	 	 	 	 d.deded
eded#ee   d$ee   d%ee(e      d&e)d'e*d(   de"eef   fd)Z+dej,                  dedefd*Z,deded
edede"eef   f
d+Z-dej,                  dedefd,Z.y)/OpenAIResponsesAPIConfigreturnc                 "    t         j                  S N)r   OPENAI)selfs    /Users/manta/Documents/Projects/TheRoad-I1/backend/.venv/lib/python3.12/site-packages/litellm/llms/openai/responses/transformation.pycustom_llm_providerz,OpenAIResponsesAPIConfig.custom_llm_provider   s    """    modelc                     t        t              j                         }t        t	        g dt        |      z               S )z?
        All OpenAI Responses API params are supported
        )inputr!   extra_headersextra_query
extra_bodytimeout)r	   ResponsesAPIRequestParamskeyslistset)r   r!   supported_paramss      r   get_supported_openai_paramsz4OpenAIResponsesAPIConfig.get_supported_openai_params"   sC     **CDIIK '()

 	
r    response_api_optional_paramsdrop_paramsc                     t        |      S )z:No mapping applied since inputs are in OpenAI spec already)dict)r   r.   r!   r/   s       r   map_openai_paramsz*OpenAIResponsesAPIConfig.map_openai_params5   s     011r    r#   $response_api_optional_request_paramslitellm_paramsheadersc                 V    | j                  |      }t        t        d||d|      }|S )z<No transform applied since inputs are in OpenAI spec already)r!   r#    )_validate_input_paramr1   r(   )r   r!   r#   r3   r4   r5   final_request_paramss          r   transform_responses_api_requestz8OpenAIResponsesAPIConfig.transform_responses_api_request>   sA     **51#% 5,P 
 $#r    c                    t        |t              rg }|D ]  }t        |t              r"|j                  |j	                  d             5t        |t
              rt        j                  d|        |j                  d      dk(  r/t        t        t        t        f   |      }| j                  |      }nt        t        t        t        f   |      }|j                  |       |j                  |        |S |S )z
        Ensure all input fields if pydantic are converted to dict

        OpenAI API Fails when we try to JSON dumps specific input pydantic fields.
        This function ensures all input fields are converted to dict.
        Texclude_nonezHandling reasoning item: type	reasoning)
isinstancer*   r   append
model_dumpr1   r   debuggetr   r   strr   _handle_reasoning_item)r   r#   validated_inputitem	dict_itemfiltered_items         r   r8   z.OpenAIResponsesAPIConfig._validate_input_paramQ   s     eT" OdI.#**4???+MNd+"((+DTF)KLxx';6$(c3h$>	(,(C(CI(N )-T#s(^T(B#**=9#**40! " #"r    rH   c                    |j                  d      dk(  rz	 t        |      }d|vrKt        |j                  dd            dkD  r|j                  dd      dd dz   n|j                  dd      |d<   t        di |}|j	                  d	
      }|S |S # t
        $ rT}t        j                  d|        |j                         D ci c]  \  }}||dvr|| nc c}}w }}}|cY d}~S d}~ww xY w)a  
        Handle reasoning items specifically to filter out status=None using OpenAI's model.
        Issue: https://github.com/BerriAI/litellm/issues/13484
        OpenAI API does not accept ReasoningItem(status=None), so we need to:
        1. Check if the item is a reasoning type
        2. Create a ResponseReasoningItem object with the item data
        3. Convert it back to dict with exclude_none=True to filter None values
        r>   r?   summaryreasoning_content d   Nz...Tr<   zJFailed to create ResponseReasoningItem, falling back to manual filtering: >   statuscontentencrypted_contentr7   )	rD   r1   lenr
   rB   	Exceptionr   rC   items)	r   rH   	item_datareasoning_itemdict_reasoning_itemekvrJ   s	            r   rF   z/OpenAIResponsesAPIConfig._handle_reasoning_itemq   s"    88F{*% J	I- y}}-@"EFL "&92>tDuL&]]+>C i( "7!C!C '5&?&?T&?&R#**   %$$`ab`cd !%

! ,1} JJ qD ,! ! %$%s*   A8B 	C.+C)CC)#C.)C.raw_responselogging_objc                    	 |j                  |j                  di i       |j                         }t        |d         |d<   t        |j                        }t        |      }	 t        d	i |}||j                  d<   ||j                  d<   |S # t        $ r" t        |j                  |j                        w xY w# t        $ r1 t        j                  d| d       t        j                  d	i |}Y w xY w)
z=No transform applied since outputs are in OpenAI spec alreadycomplete_input_dict)original_responseadditional_args
created_atmessagestatus_codez)Error constructing ResponsesAPIResponse: z, using model_constructadditional_headersr5   r7   )	post_calltextjsonr   rT   r   re   r1   r5   r   ResponsesAPIResponser   rC   model_construct_hidden_params)r   r!   r\   r]   raw_response_jsonraw_response_headersprocessed_headersresponses           r   transform_response_api_responsez8OpenAIResponsesAPIConfig.transform_response_api_response   s$   	!!"."3"3!6 ; "  !- 1 1 3.I!,//l+  $L$8$8945IJ	Q+@.?@H 9J 45-A	*!  	$))|7O7O 	  	Q  ;<M;NNef ,;;P>OPH		Qs   A B #B< +B9<7C65C6c                     |xs
 t               }|j                  xs/ t        j                  xs t        j                  xs t	        d      }|j                  dd| i       |S )NOPENAI_API_KEYAuthorizationzBearer )r   api_keylitellm
openai_keyr   update)r   r5   r!   r4   ru   s        r   validate_environmentz-OpenAIResponsesAPIConfig.validate_environment   sp     (A+?+A"" 00!!0 ./	 	 	77)!4	

 r    api_basec                     |xs. t         j                  xs t        d      xs t        d      xs d}|j                  d      }| dS )z;
        Get the endpoint for OpenAI responses API
        OPENAI_BASE_URLOPENAI_API_BASEzhttps://api.openai.com/v1/z
/responses)rv   rz   r   rstrip)r   rz   r4   s      r   get_complete_urlz)OpenAIResponsesAPIConfig.get_complete_url   s_      ++/0+ /0+ + 	 ??3':&&r    parsed_chunkc                     t        j                  d|       t        |j                  d            }t        j                  |      } |di |S )zb
        Transform a parsed streaming response chunk into a ResponsesAPIStreamingResponse
        zRaw OpenAI Chunk=%sr>   )
event_typer7   )r   rC   rE   rD   r   get_event_model_class)r   r!   r   r]   r   event_pydantic_models         r   transform_streaming_responsez5OpenAIResponsesAPIConfig.transform_streaming_response   sT     	2LA))&12
7MM!  N  
 $3l33r    r   c                 ~   i t         j                  t        t         j                  t        t         j
                  t        t         j                  t        t         j                  t        t         j                  t        t         j                  t        t         j                  t         t         j"                  t$        t         j&                  t(        t         j*                  t,        t         j.                  t0        t         j2                  t4        t         j6                  t8        t         j:                  t<        t         j>                  t@        t         jB                  tD        t         jF                  tH        t         jJ                  tL        t         jN                  tP        t         jR                  tT        t         jV                  tX        t         jZ                  t\        t         j^                  t`        t         jb                  td        t         jf                  th        t         jj                  tl        t         jn                  tp        t         jr                  tt        t         jv                  tx        t         jz                  t|        t         j~                  t        i}|j                  t        t         |             }|st        S |S )a8  
        Returns the appropriate event model class based on the event type.

        Args:
            event_type (str): The type of event from the response chunk

        Returns:
            Any: The corresponding event model class

        Raises:
            ValueError: If the event type is unknown
        )DResponsesAPIStreamEventsRESPONSE_CREATEDResponseCreatedEventRESPONSE_IN_PROGRESSResponseInProgressEventRESPONSE_COMPLETEDResponseCompletedEventRESPONSE_FAILEDResponseFailedEventRESPONSE_INCOMPLETEResponseIncompleteEventOUTPUT_ITEM_ADDEDOutputItemAddedEventOUTPUT_ITEM_DONEOutputItemDoneEventCONTENT_PART_ADDEDContentPartAddedEventCONTENT_PART_DONEContentPartDoneEventOUTPUT_TEXT_DELTAOutputTextDeltaEventOUTPUT_TEXT_ANNOTATION_ADDEDOutputTextAnnotationAddedEventOUTPUT_TEXT_DONEOutputTextDoneEventREFUSAL_DELTARefusalDeltaEventREFUSAL_DONERefusalDoneEventFUNCTION_CALL_ARGUMENTS_DELTAFunctionCallArgumentsDeltaEventFUNCTION_CALL_ARGUMENTS_DONEFunctionCallArgumentsDoneEventFILE_SEARCH_CALL_IN_PROGRESSFileSearchCallInProgressEventFILE_SEARCH_CALL_SEARCHINGFileSearchCallSearchingEventFILE_SEARCH_CALL_COMPLETEDFileSearchCallCompletedEventWEB_SEARCH_CALL_IN_PROGRESSWebSearchCallInProgressEventWEB_SEARCH_CALL_SEARCHINGWebSearchCallSearchingEventWEB_SEARCH_CALL_COMPLETEDWebSearchCallCompletedEventMCP_LIST_TOOLS_IN_PROGRESSMCPListToolsInProgressEventMCP_LIST_TOOLS_COMPLETEDMCPListToolsCompletedEventMCP_LIST_TOOLS_FAILEDMCPListToolsFailedEventMCP_CALL_IN_PROGRESSMCPCallInProgressEventMCP_CALL_ARGUMENTS_DELTAMCPCallArgumentsDeltaEventMCP_CALL_ARGUMENTS_DONEMCPCallArgumentsDoneEventMCP_CALL_COMPLETEDMCPCallCompletedEventMCP_CALL_FAILEDMCPCallFailedEventIMAGE_GENERATION_PARTIAL_IMAGE ImageGenerationPartialImageEventERROR
ErrorEventrD   r   GenericEvent)r   event_modelsmodel_classs      r   r   z.OpenAIResponsesAPIConfig.get_event_model_class   s-   !
$557K!
$99;R!
 %779O!
 %446I	!

 %88:Q!
 %668L!
 %557J!
 %779N!
 %668L!
 %668L!
 %AACa!
 %557J!
 %224E!
 %113C!
 %BBDc!
  %AACa!!
" %AAC`#!
$ %??A]$??A]$@@B^$>>@[$>>@[$??A\$==?Y$::<S$99;Q$==?Y$<<>W$779N$446H$CCEe$**JA!
F #&&t,Dj'QRr    Nstreamr   c                     |dury|'	 t         j                  j                  ||      du ry	 yy# t        $ r"}t	        j
                  d|        Y d }~yd }~ww xY w)NTF)r!   r   z6Error getting model info in OpenAIResponsesAPIConfig: )rv   utilssupports_native_streamingrT   r   rC   )r   r!   r   r   rY   s        r   should_fake_streamz+OpenAIResponsesAPIConfig.should_fake_stream*  s     MM;;#,? <  	   	  $$LQCP  	s   #0 	AAAresponse_idc                     | d| }i }||fS )z
        Transform the delete response API request into a URL and data

        OpenAI API expects the following request
        - DELETE /v1/responses/{response_id}
        r~   r7   r   r   rz   r4   r5   urldatas          r   %transform_delete_response_api_requestz>OpenAIResponsesAPIConfig.transform_delete_response_api_requestE  #     
!K=)Dyr    c                     	 |j                         }t        di |S # t        $ r" t        |j                  |j                        w xY w)zX
        Transform the delete response API response into a DeleteResponseResult
        rc   r7   )ri   rT   r   rh   re   DeleteResponseResult)r   r\   r]   rm   s       r   &transform_delete_response_api_responsez?OpenAIResponsesAPIConfig.transform_delete_response_api_responseV  sV    	 , 1 1 3
 $8&788	  	$))|7O7O 	s	    +Ac                     | d| }i }||fS )z
        Transform the get response API request into a URL and data

        OpenAI API expects the following request
        - GET /v1/responses/{response_id}
        r~   r7   r   s          r   "transform_get_response_api_requestz;OpenAIResponsesAPIConfig.transform_get_response_api_requesti  r   r    c                    	 |j                         }t        |j                        }t        |      }t        di |}||j                  d<   ||j                  d<   |S # t        $ r" t        |j                  |j                        w xY w)zU
        Transform the get response API response into a ResponsesAPIResponse
        rc   rf   r5   r7   
ri   rT   r   rh   re   r1   r5   r   rj   rl   r   r\   r]   rm   rn   ro   rp   s          r   #transform_get_response_api_responsez<OpenAIResponsesAPIConfig.transform_get_response_api_responsez      	 , 1 1 3
  $L$8$8945IJ'<*;<8I 45-A	*  	$))|7O7O 	   A +Bafterbeforeincludelimitorder)ascdescc
                     | d| d}
i }|||d<   |||d<   |rdj                  |      |d<   |||d<   |	|	|d<   |
|fS )	Nr~   z/input_itemsr   r   ,r   r   r   )join)r   r   rz   r4   r5   r   r   r   r   r   r   paramss               r   "transform_list_input_items_requestz;OpenAIResponsesAPIConfig.transform_list_input_items_request  sx     
!K=5!##F7O%F8 # 1F9#F7O#F7OF{r    c                     	 |j                         S # t        $ r" t        |j                  |j                        w xY w)Nrc   )ri   rT   r   rh   re   )r   r\   r]   s      r   #transform_list_input_items_responsez<OpenAIResponsesAPIConfig.transform_list_input_items_response  sC    
	$$&& 	$))|7O7O 	s    +=c                     | d| d}i }||fS )z
        Transform the cancel response API request into a URL and data

        OpenAI API expects the following request
        - POST /v1/responses/{response_id}/cancel
        r~   z/cancelr7   r   s          r   %transform_cancel_response_api_requestz>OpenAIResponsesAPIConfig.transform_cancel_response_api_request  s%     
!K=0Dyr    c                    	 |j                         }t        |j                        }t        |      }t        di |}||j                  d<   ||j                  d<   |S # t        $ r" t        |j                  |j                        w xY w)zX
        Transform the cancel response API response into a ResponsesAPIResponse
        rc   rf   r5   r7   r   r   s          r   &transform_cancel_response_api_responsez?OpenAIResponsesAPIConfig.transform_cancel_response_api_response  r   r   r   )NNN   r   )/__name__
__module____qualname__propertyr   r   rE   r*   r-   !ResponsesAPIOptionalRequestParamsboolr   r2   r   ResponseInputParamr   r1   r:   r8   r   rF   httpxResponseLiteLLMLoggingObjrj   rq   r   ry   r   ResponsesAPIStreamingResponser   staticmethodr   r   Tupler   r   r   r   r   ListintLiteralr   r   r   r   r7   r    r   r   r      s   #\ # #
 
 
&2&G2 2 	2
 
2$$ S,,-$ /3	$
 -$ $ 
$&3 223	s&&	'@'4S> 'd38n 'R   nn  '	 
 
 D$'9ABV9W	"'3-' ' 
	'*44 4 '	4
 
'4" 4# 4# 4 4t .2	}  &c]	
 
6  -	
  
sDy	"9nn9 '9 
	9&  -	
  
sDy	"nn ' 
	@  $ $'+(.  -	
  }  $s)$  }% 
sDy	4
nn
 '
 
	
  -	
  
sDy	"nn ' 
	r    r   )%typingr   r   r   r   r   r   r	   r   openai.types.responsesr
   pydanticr   rv   litellm._loggingr   Flitellm.litellm_core_utils.llm_response_utils.convert_dict_to_responser   .litellm.llms.base_llm.responses.transformationr   litellm.secret_managers.mainr   litellm.types.llms.openailitellm.types.responses.mainlitellm.types.routerr   litellm.types.utilsr   'litellm.litellm_core_utils.core_helpersr   common_utilsr   *litellm.litellm_core_utils.litellm_loggingr   _LiteLLMLoggingObjr   r   r7   r    r   <module>r     s^    R R R  8   + R 7 ' * 5 , L &X*F5 Fr    