
    AHjq                         d dl Z d dlmZmZmZmZmZmZmZ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mZmZmZ d dlmZ d dlmZmZmZmZ  G d	 d
      Z G d d      Z y)    N)
AnyDictIterableListOptionalTypeUnioncastget_type_hintsoverload)	BaseModel)verbose_logger)BaseResponsesAPIConfig)ResponseAPIUsage!ResponsesAPIOptionalRequestParamsResponsesAPIResponseResponseText)DecodedResponseId)CompletionTokensDetailsWrapperPromptTokensDetailsWrapperSpecialEnumsUsagec                      e Zd ZdZedeee      dedee	   dee   def
d       Z
e	 d1ded	ed
edeee      def
d       Zedeeef   defd       Zee	 d1dedee   deeeef      defd              Zee	 d1deeef   dee   deeeef      deeef   fd              Ze	 d1deeeeef   f   dee   deeeef      deeeeef   f   fd       Zedededefd       Zededeeeef      fd       Zedededefd       Zededeee   ef   fd       Zededeeef   f   dee   dedeeef   f   fd        Zed!edefd"       Zedee   dee   d#edefd$       Zed#edefd%       Zed#ee   dee   fd&       Zed'edefd(       Ze	 d1d)eee d*   e!f      d+ed,   ded,   fd-       Z"ed.eeeef      d/ee#e      deee   eeeeeef   f      eeeef      eeeef      f   fd0       Z$y)2ResponsesAPIRequestUtilsz2Helper utils for constructing ResponseAPI requestssupported_paramsnon_default_paramsdrop_paramscustom_llm_providermodelc           	          | y i }|j                         D ]  }|| vs||   ||<    |r9t        j                  du s||du ry t        j                  d| d| d| d      y )NTi  z does not support parameters: z, for model=zf. To drop these, set `litellm.drop_params=True` or for proxy:

`litellm_settings:
 drop_params: true`
)status_codemessage)keyslitellmr   UnsupportedParamsError)r   r   r   r   r   unsupported_paramsks          O/root/tools/cai/cai_env/lib/python3.12/site-packages/litellm/responses/utils.py_check_valid_argz)ResponsesAPIRequestUtils._check_valid_arg&   s     ##((* 	>A(((:1(="1%	> ""d*'K4,?44 #233QRdQeeqrwqx  yc  d      Nresponses_api_provider_configresponse_api_optional_paramsallowed_openai_paramsreturnc                 (   ddl m} |j                  |       }t        t        |      }t
        j                  ||xs g z   |t        j                  |j                  |        |j                  || t        j                        } ||||xs g       }|S )aS  
        Get optional parameters for the responses API.

        Args:
            params: Dictionary of all parameters
            model: The model name
            responses_api_provider_config: The provider configuration for responses API

        Returns:
            A dictionary of supported parameters for the responses API
        r   )_apply_openai_param_overrides)r   r   r   r   r   )r,   r   r   )optional_paramsr   r-   )litellm.utilsr0   get_supported_openai_paramsr
   r   r   r)   r$   r   r   map_openai_params)r   r+   r,   r-   r0   r   r   mapped_paramss           r(   !get_optional_params_responses_apiz:ResponsesAPIRequestUtils.get_optional_params_responses_api?   s    $ 	@ 9TT
 "$(DE 11-1F1L"M1++ = Q Q 	2 	
 6GG)E++ H 
 6)1"7"=2
 r*   paramsc                    ddl m} t        t              j	                         }| j                  dd      }| j                  di       }| j                  dd      }|j                  | ||||D ci c]  }|d c}dg      }d	|v rt        j                  |d	         }||d	<   d
|v r+ddl m	}	  |	|d
         }
|
|
|d
<   n|j                  d
d       t        t        |      S c c}w )a  
        Filter parameters to only include those defined in ResponsesAPIOptionalRequestParams.

        Args:
            params: Dictionary of parameters to filter

        Returns:
            ResponsesAPIOptionalRequestParams instance with only the valid parameters
        r   )PreProcessNonDefaultParamsr   Nkwargsadditional_drop_paramsinput)passed_paramsspecial_paramsr   r;   default_param_values#additional_endpoint_specific_paramsprevious_response_idmetadata)add_openai_metadata)r2   r9   r   r   r#   pop#base_pre_process_non_default_paramsr   <decode_previous_response_id_to_original_previous_response_idrC   r
   )r7   r9   
valid_keysr   r>   r;   r'   r   decoded_previous_response_idrC   converted_metadatas              r(   )get_requested_response_api_optional_paramzBResponsesAPIRequestUtils.get_requested_response_api_optional_params   s    	=#$EFKKM
$jj)>EHb1!',Dd!K&JJ$-$7'=7A%B!ag%B5<I K  	 "%77+C  ,A  ,A"#9:,( :V56++9!45G
5S!T!-1C":."&&z4857IJJ+ &Cs   -
C!responses_api_responselitellm_metadatac                      y N rK   r   rL   s      r(   /_update_responses_api_response_id_with_model_idzHResponsesAPIRequestUtils._update_responses_api_response_id_with_model_id        	r*   c                      y rN   rO   rP   s      r(   rQ   zHResponsesAPIRequestUtils._update_responses_api_response_id_with_model_id   rR   r*   c                    |xs i }|j                  di       xs i }|j                  d      }t        | t              r| j                  d      }nt        | dd      }|| S t        j                  |||      }t        | t              r|| d<   n|| _        |j                  d      rt        j                  | |      } | S )zUpdate the responses_api_response_id with model_id and custom_llm_provider.

        Handles both ``ResponsesAPIResponse`` objects and plain dictionaries returned
        by some streaming providers.
        
model_infoidN)model_idr   response_id"encrypted_content_affinity_enabled)responserW   )get
isinstancedictgetattrr    _build_responses_api_response_idrV   ._update_encrypted_content_item_ids_in_response)rK   r   rL   rU   rW   rX   
updated_ids          r(   rQ   zHResponsesAPIRequestUtils._update_responses_api_response_id_with_model_id   s     ,1r%5%9%9,%K%Qr
>>$' ,d3044T:K!"8$EK ))-NN 3# O 

 ,d3+5"4((2"% DE(WW3% X  # &%r*   rW   item_idc                     d|  d| }t        j                  |j                  d            j                  d      }d| S )zEncode model_id into an output item ID for encrypted-content items.

        Format: ``encitem_{base64("litellm:model_id:{model_id};item_id:{original_id}")}``
        litellm:model_id:z	;item_id:utf-8encitem_base64	b64encodeencodedecode)rW   rb   	assembledencodeds       r(   _build_encrypted_item_idz1ResponsesAPIRequestUtils._build_encrypted_item_id   sI     (z7)D	""9#3#3G#<=DDWM'##r*   
encoded_idc                    | j                  d      sy	 | t        d      d }t        |      dz  }|r|dd|z
  z  z  }t        j                  |j	                  d            j                  d      }|j                  dd      }t        |      dk  ry|d	   j                  d
d      }|d   j                  dd      }||dS # t        $ r Y yw xY w)zDecode a litellm-encoded encrypted-content item ID.

        Returns a dict with ``model_id`` and ``item_id`` keys, or ``None`` if
        the string is not a litellm-encoded item ID.
        rf   N   =re   ;      r   rd    zitem_id:)rW   rb   )	
startswithlenrh   	b64decoderj   rk   splitreplace	Exception)ro   cleanedmissingdecodedpartsrW   rb   s          r(   _decode_encrypted_item_idz2ResponsesAPIRequestUtils._decode_encrypted_item_id   s     $$Z0	 Z!23G'lQ&G3!g+..&&w~~g'>?FFwOGMM#q)E5zA~Qx''(;R@HAh&&z26G (W== 		s   A<C  .C   	CCencrypted_contentc                     d| }t        j                  |j                  d            j                  d      }d| d|  S )aG  Wrap encrypted_content with model_id metadata for affinity routing.

        When Codex or other clients send items with encrypted_content but no ID,
        we encode the model_id directly into the encrypted_content itself.

        Format: ``litellm_enc:{base64("model_id:{model_id}")};{original_encrypted_content}``
        	model_id:re   litellm_enc:rs   rg   )r   rW   rB   encoded_metadatas       r(   %_wrap_encrypted_content_with_model_idz>ResponsesAPIRequestUtils._wrap_encrypted_content_with_model_id  sL     xj)!++HOOG,DELLWU./q1B0CDDr*   wrapped_contentc                    | j                  d      sd| fS 	 | j                  dd      }t        |      dk  rd| fS |d   j                  dd      }|d   }t        |      dz  }|r|d	d|z
  z  z  }t	        j
                  |j                  d
            j                  d
      }|j                  dd      }||fS # t        $ r d| fcY S w xY w)zUnwrap encrypted_content to extract model_id and original content.

        Returns:
            Tuple of (model_id, original_encrypted_content).
            If not wrapped, returns (None, original_content).
        r   Nrs   rt   ru   r   rv   rq   rr   re   r   )	rw   rz   rx   r{   rh   ry   rj   rk   r|   )r   r   metadata_b64original_contentr~   decoded_metadatarW   s          r(   '_unwrap_encrypted_content_with_model_idz@ResponsesAPIRequestUtils._unwrap_encrypted_content_with_model_id  s     )).9((	)#))#q1E5zA~_,, 8++NB?L$Qx ,'!+Gq7{ 33%//0C0CG0LMTT  (//R@H--- 	)((	)s   #B9 A=B9 9C	C	rZ   r   c                    |s| S d}t        | t              r| j                  d      }nt        | dd      }t        |t              s| S |D ]
  }t        |t              r}|j                  d      }|j                  d      }|s9t        |t
              sJt        j                  ||      |d<   |sft        |t
              swt        j                  ||      |d<   t        |dd      }t        |dd      }|st        |t
              s	 t        j                  ||      |_	        |st        |t
              s	 t        j                  ||      |_         | S # t        $ r Y @w xY w# t        $ r Y +w xY w)ae  Rewrite item IDs for output items that contain ``encrypted_content``.

        Encodes ``model_id`` into the item ID so that follow-up requests can be
        routed back to the originating deployment without any cache lookup.

        For items without an ID (e.g., from Codex), encodes model_id directly
        into the encrypted_content itself.
        NoutputrV   r   )r\   r]   r[   r^   liststrr   r   rn   r   AttributeErrorrV   )rZ   rW   r   itemrb   r   s         r(   r`   zGResponsesAPIRequestUtils._update_encrypted_content_item_ids_in_response=  sv    O!%h%\\(+FXx6F&$'O $	!D$%((4.$(HH-@$A!$4Es)K 1VV)8 + :gs#;%=%V%V$g&T
 "$d3$+D2Et$L!$4Es)K1I1o1o-x2. :gs#;!&>&W&W (''DGA$	!L  *   . ! !s$   
E:E)	E&%E&)	E65E6request_inputc                 n   t        | t              s| S | D ]  }t        |t              s|j                  d      }|r/t        |t              rt
        j                  |      }|r|d   |d<   |j                  d      }|sjt        |t              s{t
        j                  |      \  }}||k7  s||d<    | S )aw  Decode litellm-encoded item IDs in request input back to original IDs.

        Called before forwarding the request to the upstream provider so the
        provider receives the original item IDs and unwrapped encrypted_content.

        Handles both:
        1. Items with encoded IDs (encitem_...)
        2. Items with wrapped encrypted_content (litellm_enc:...)
        rV   rb   r   )r\   r   r]   r[   r   r   r   r   )r   r   rb   r   r   _	unwrappeds          r(   ,_restore_encrypted_content_item_ids_in_inputzEResponsesAPIRequestUtils._restore_encrypted_content_item_ids_in_input~  s     -.  ! 	>D$%((4.z'376PPG %,Y%7T
$(HH-@$A!$4Es)K 1XX)! !$554=01'	>* r*   rX   c                     t        t        j                  j                        j	                  | ||      }t        j                  |j                  d            j                  d      }d| S )z#Build the responses_api_response_idre   resp_)	r   r   %LITELLM_MANAGED_RESPONSE_COMPLETE_STRvalueformatrh   ri   rj   rk   )r   rW   rX   assembled_idbase64_encoded_ids        r(   r_   z9ResponsesAPIRequestUtils._build_responses_api_response_id  sl      >>DD

&$h
< 	 "(!1!1,2E2Eg2N!O!V!V"
 ()**r*   c                 "   	 | j                  dd      }t        j                  |j                  d            j	                  d      }d|vrt        dd|       S |j                  d      }d}d}t        |      dk\  rF|d   }|d	   }|d
   }|j                  dd      }|j                  dd      }|j                  dd      }	n| }	t        |||	      S # t        $ r3}
t        j                  d|  d|
        t        dd|       cY d}
~
S d}
~
ww xY w)z
        Decode the responses_api_response_id

        Returns:
            DecodedResponseId: Structured tuple with custom_llm_provider, model_id, and response_id
        r   rv   re   rs   N)r   rW   rX      r   rt   ru   zlitellm:custom_llm_provider:r   zresponse_id:zError decoding response_id 'z': )r{   rh   ry   rj   rk   r   rz   rx   r|   r   debug)rX   
cleaned_id
decoded_idr   r   rW   custom_llm_provider_partmodel_id_partresponse_partdecoded_response_ides              r(   !_decode_responses_api_response_idz:ResponsesAPIRequestUtils._decode_responses_api_response_id  sE   -	$,,Wb9J))**;*;G*DELLWUJ *$((,! +  $$S)E #'H E
a+08( %a %a&>&F&F2B'# )00bA&3&;&;NB&O#&1#$$7!/ 
  	  #?}CPQs!ST$$(' 	s%   AC A8C 	D(D	D	Dc                 \    | yt         j                  |       }|j                  d      xs dS )z%Get the model_id from the response_idNrW   r   r   r[   )rX   r   s     r(   get_model_id_from_response_idz6ResponsesAPIRequestUtils.get_model_id_from_response_id  s8     $FF{S 	 #&&z2:d:r*   rA   c                 P    t         j                  |       }|j                  d|       S )aS  
        Decode the previous_response_id to the original previous_response_id

        Why?
            - LiteLLM encodes the `custom_llm_provider` and `model_id` into the `previous_response_id` this helps with maintaining session consistency when load balancing multiple deployments of the same model.
            - We cannot send the litellm encoded b64 to the upstream llm api, hence we decode it to the original `previous_response_id`

        Args:
            previous_response_id: The previous_response_id to decode

        Returns:
            The original previous_response_id
        rX   r   )rA   r   s     r(   rF   zUResponsesAPIRequestUtils.decode_previous_response_id_to_original_previous_response_id  s0    $ %FF$ 	
 #&&}6JKKr*   text_formatr   textr   c                 n    | 2|0ddl m}  ||       }| d|d   |d   d   |d   d   |d   d   d	i}|S |S )
at  
        Convert text_format parameter to text parameter for the responses API.

        Args:
            text_format: Pydantic model class or dict to convert to response format
            text: Existing text parameter (if provided, text_format is ignored)

        Returns:
            ResponseText object with the converted format, or None if conversion fails
        r   )type_to_response_format_paramr   typejson_schemanameschemastrict)r   r   r   r   ) litellm.llms.base_llm.base_utilsr   )r   r   r   response_formats       r(   !convert_text_format_to_text_paramz:ResponsesAPIRequestUtils.convert_text_format_to_text_param  so     "t|V <KHO*  / 7 / >v F"1-"@"J"1-"@"J	 r*   secret_fieldstoolsc                 r   ddl m} ddlm} d}| r!t	        | t
              r| j                  d      }d}d}d}|r; ||      }|j                  |      }|j                  |      }|j                  |      }|r|D ]  }	t	        |	t
              s|	j                  d      dk(  s)|	j                  di       }
|
s>t	        |
t
              sO ||
      }|j                  |      }|r9|i }|j                         D ]"  \  }}||vri ||<   ||   j                  |       $ |i }|j                  |
        ||||fS )	z
        Extract MCP auth headers from the request to pass to MCP server.
        Headers from tools.headers in request body should be passed to MCP server.
        r   )Headers)MCPRequestHandlerNraw_headersr   mcpheaders)starlette.datastructuresr   Alitellm.proxy._experimental.mcp_server.auth.user_api_key_auth_mcpr   r\   r]   r[   !_get_mcp_auth_header_from_headers)_get_mcp_server_auth_headers_from_headers _get_oauth2_headers_from_headersitemsupdate)r   r   r   r   raw_headers_from_requestmcp_auth_headermcp_server_auth_headersoauth2_headersheaders_objtooltool_headersheaders_obj_from_tooltool_mcp_server_auth_headersserver_aliasheaders_dicts                  r(    extract_mcp_headers_from_requestz9ResponsesAPIRequestUtils.extract_mcp_headers_from_request/  s    	5	

 >B Zt<'4'8'8'G$ *.GK37#!":;K/QQO "KKKX $ /OON  FdD)dhhv.>%.G#'88Ir#:L#
<(F 180E--WW 5 5
 86>:< 7
 ">!C!C!E" ! , ,#/7N#NLN$;L$I 7 E L L$0!"" 4;794077E9F> #$	
 	
r*   rN   )%__name__
__module____qualname____doc__staticmethodr   r   r   r   boolr)   r   r   r6   r   rJ   r   r   rQ   r	   rn   r   r   tupler   r`   r   r_   r   r   r   rF   r   r]   r   r   r   rO   r*   r(   r   r   #   s   <"49-  d^ &c]	
  0 
 6:	11'=1 'H1  (S	2	1
 
1 1f .KS#X.K	*.K .Kb  6: 4%c] #4S>2 
	    6: $S#X%c] #4S>2 
c3h	    6:+& %&:DcN&J K+&%c]+& #4S>2+& 
#T#s(^3	4	+& +&Z $3 $ $ $ $ c htCH~6N  2 EE*-E	E E  ) )	x}c!	" )  )D >.S#X>?>3-> 
%tCH~5	6> >@ "C "C " "H +%c]+3-+ + 
	+ + 66	6 6p ;8C= ;Xc] ; ; L!L	L L.  *.eD$5t$;<=~& 
.	! B M
S#X/M
&M
 
c4S>)*+c3h c3h 	"
M
 M
r*   r   c                   Z    e Zd Zedeeef   defd       Zede	eeef      de
fd       Zy)ResponseAPILoggingUtilsusager.   c                 8    t        | t              ryd| v rd| v ryy)z1returns True if usage is from OpenAI Response APITinput_tokensoutput_tokensF)r\   r   )r   s    r(   _is_response_api_usagez.ResponseAPILoggingUtils._is_response_api_usage  s'     e-.U"%'?r*   usage_inputc           
      n   | t        ddd      S t        | t              rO| j                  d      }|0| j                  d      }| j                  d      }||
||z   }|| d<   t	        di | }n| }|j
                  xs d}|j                  xs d}d}|j                  rt        |j                  t              rt        di |j                  }nct        t        |j                  dd      t        |j                  dd      t        |j                  d	d      t        |j                  d
d            }d}t        |dd      }	|	r/t        t        |	dd      t        |	d
d      t        |	d	d            }t        ||||z   ||      }
t        |d      r#|j                  t        |
d|j                         |
S )z
        Transforms ResponseAPIUsage or ImageUsage to a Usage object.

        Both have the same spec with input_tokens, output_tokens, and
        input_tokens_details (text_tokens, image_tokens).
        Nr   )prompt_tokenscompletion_tokenstotal_tokensr   r   r   cached_tokensaudio_tokenstext_tokensimage_tokens)r   r   r   r   output_tokens_detailsreasoning_tokens)r   r   r   )r   r   r   prompt_tokens_detailscompletion_tokens_detailscostrO   )r   r\   r]   r[   r   r   r   input_tokens_detailsr   r^   r   hasattrr   setattr)r   r   r   r   response_api_usager   r   r   r   r   
chat_usages              r(   +_transform_response_api_usage_to_chat_usagezCResponseAPILoggingUtils._transform_response_api_usage_to_chat_usage  s    "#  k4(&??>:L#*~> + @+0I#/-#?L2>K/!1!@K!@!,/<<A!3!A!A!FQFJ22,AA4H(B )(==)% )C")*??RV# ")*??QU" !(*??PT! ")*??QU")% OS! ' 7!
 !(F!()+=t" %%:NDQ#$9=$O)% '/&)::"7&?

 %v.3E3J3J3VJ(:(?(?@r*   N)r   r   r   r   r	   r]   r   r   r   r   r   r   rO   r*   r(   r   r     se    eD2B,B&C    KeD*:$:;<K	K Kr*   r   )!rh   typingr   r   r   r   r   r   r	   r
   r   r   pydanticr   r$   litellm._loggingr   .litellm.llms.base_llm.responses.transformationr   litellm.types.llms.openair   r   r   r   litellm.types.responses.mainr   litellm.types.utilsr   r   r   r   r   r   rO   r*   r(   <module>r      sW         + Q  ; Z	
 Z	
zV Vr*   