Ë
    uPêj·}  ã                   ó°  — d Z ddlZddlZddlmZmZmZ ddl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ZddlmZ ddlmZmZmZ ddlmZmZ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)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z; ddl<m=Z= erddl>Z>ddl?m@ZA ddl"mBZB ddl)mCZC eAZDne	ZD G d„ de#e%«      ZE G d„ de!«      ZFy)z
Support for gpt model family
é    N)ÚAsyncIteratorÚ	CoroutineÚIterator)ÚTYPE_CHECKINGÚAnyÚFinalÚLiteralÚOptionalÚcastÚoverload)Úurlparse)Úmap_finish_reason)Ú_extract_reasoning_contentÚ#_handle_invalid_parallel_tool_callsÚ&_should_convert_tool_call_to_json_mode)Ú,drop_tool_reference_parts_from_tool_messagesÚget_tool_call_namesÚhoist_images_from_tool_messages)Úasync_convert_url_to_base64Úconvert_url_to_base64)ÚBaseModelResponseIterator)ÚBaseLLMModelInfo)Ú
BaseConfigÚBaseLLMException)Úget_secret_str)ÚAllMessageValuesÚChatCompletionFileObjectÚChatCompletionFileObjectFileÚChatCompletionImageObjectÚChatCompletionImageUrlObjectÚOpenAIChatCompletionChoicesÚOpenAIMessageContentListBlock)Ú#ChatCompletionMessageCustomToolCallÚChatCompletionMessageToolCallÚChoicesÚFunctionÚMessageÚModelResponseÚModelResponseStreamÚ#chat_completion_tool_call_from_dict)Ú convert_to_model_response_objecté   )ÚOpenAIError)ÚLogging)ÚBaseTokenCounter©ÚChatCompletionToolParamc                   óV  ‡ — e Zd ZU dZdZdZedz  ed<   dZe	e
z  dz  ed<   dZedz  ed<   dZe
dz  ed<   dZedz  ed<   dZedz  ed	<   dZedz  ed
<   dZe	ez  dz  ed<   dZedz  ed<   dZedz  ed<   dZe
dz  ed<   	 	 	 	 	 	 	 	 	 	 	 dQdedz  de	e
z  dz  dedz  de
dz  dedz  d	edz  d
edz  de	ez  dz  dedz  dedz  de
dz  ddfd„Zeˆ fd„«       Zde	defd„Zde
de
de	dede
f
d„Zde
de
de	dede
f
d„Zdedefd„Zdedefd„Zdedefd„Zdedefd„Z de!de!fd„Z"de!de!fd„Z#	 dRde!d!ede!fd"„Z$e%d#ee&   de	d!e'd   de(e)e)ee&   f   fd$„«       Z*e%	 dRd#ee&   de	d!e'd    dee&   fd%„«       Z*	 dRd#ee&   de	d!edee&   e(e)e)ee&   f   z  fd&„Z*	 dSde	d#ee&   d'ed(   dz  de+ee&   ed(   dz  f   fd)„Z,d*e	dz  d+e	dz  defd,„Z-de	d#ee&   de
d-e
d.e
de
fd/„Z.de	d#ee&   de
d-e
d.e
de
fd0„Z/de
defd1„Z0d2e	de
de1dz  fd3„Z2d4e3d5e	de	fd6„Z4	 	 dTd7ee5   d8edz  de
dz  dee6   fd9„Z7	 	 dTde	d:e8jr                  d;e:d<e;d=e
d#ee&   de
d-e
d>d?d@e	dz  d8edz  de:fdA„Z<dBe	dCed.e
e8jz                  z  de>fdD„Z?	 dSd+e	dz  d@e	dz  de	de
d-e
dEedz  de	fdF„Z@	 	 dTd.e
de	d#ee&   de
d-e
d@e	dz  d+e	dz  de
fdG„ZAdTd@e	dz  d+e	dz  dee	   fdH„ZBeCdSd@e	dz  de	dz  fdI„«       ZDeCdSd+e	dz  de	dz  fdJ„«       ZEeCdSde	dz  de	dz  fdK„«       ZFdeGdL   fdM„ZH	 dRdNeIe	   eJe	   z  e:z  dOed8edz  de)fdP„ZKˆ xZLS )UÚOpenAIGPTConfiga  
    Reference: https://platform.openai.com/docs/api-reference/chat/create

    The class `OpenAIConfig` provides configuration for the OpenAI's Chat API interface. Below are the parameters:

    - `frequency_penalty` (number or null): Defaults to 0. Allows a value between -2.0 and 2.0. Positive values penalize new tokens based on their existing frequency in the text so far, thereby minimizing repetition.

    - `function_call` (string or object): This optional parameter controls how the model calls functions.

    - `functions` (array): An optional parameter. It is a list of functions for which the model may generate JSON inputs.

    - `logit_bias` (map): This optional parameter modifies the likelihood of specified tokens appearing in the completion.

    - `max_tokens` (integer or null): This optional parameter helps to set the maximum number of tokens to generate in the chat completion.

    - `n` (integer or null): This optional parameter helps to set how many chat completion choices to generate for each input message.

    - `presence_penalty` (number or null): Defaults to 0. It penalizes new tokens based on if they appear in the text so far, hence increasing the model's likelihood to talk about new topics.

    - `stop` (string / array / null): Specifies up to 4 sequences where the API will stop generating further tokens.

    - `temperature` (number or null): Defines the sampling temperature to use, varying between 0 and 2.

    - `top_p` (number or null): An alternative to sampling with temperature, used for nucleus sampling.
    TNÚfrequency_penaltyÚfunction_callÚ	functionsÚ
logit_biasÚ
max_tokensÚnÚpresence_penaltyÚstopÚtemperatureÚtop_pÚresponse_formatÚreturnc                 óÆ   — t        «       j                  «       }|j                  «       D ]%  \  }}|dk7  sŒ|€Œt        | j                  ||«       Œ' d| j                  _        y )NÚselfF)ÚlocalsÚcopyÚitemsÚsetattrÚ	__class__Ú_is_base_class)rA   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   Úlocals_ÚkeyÚvalues                  úp/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/openai/chat/gpt_transformation.pyÚ__init__zOpenAIGPTConfig.__init__n   sT   € ô  ›Ÿ™›ˆØ!Ÿ-™-›/ò 	4‰JˆC�Ø�f‹} Ñ!2Ü˜Ÿ™¨¨UÕ3ð	4ð ).ˆ�‰Õ%ó    c                 ó    •— t         ‰| �  «       S ©N)ÚsuperÚ
get_config)ÚclsrF   s    €rK   rQ   zOpenAIGPTConfig.get_configƒ   s   ø€ ä‰wÑ!Ó#Ð#rM   Úmodelc                 óî   — g d¢}g }|dk7  r|dk7  r|j                  d«       d|v r|j                  dd«      d   n|}|t        j                  v s|t        j                  v r|j                  d«       ||z   S )N)r4   r7   ÚlogprobsÚtop_logprobsr8   Úmax_completion_tokensÚ
modalitiesÚ
predictionr9   r:   Úseedr;   ÚstreamÚstream_optionsr<   r=   ÚtoolsÚtool_choicer5   r6   Úmax_retriesÚextra_headersÚparallel_tool_callsÚaudioÚweb_search_optionsÚservice_tierÚsafety_identifierÚprompt_cache_keyÚprompt_cache_retentionÚstorezgpt-3.5-turbo-16kzgpt-4r>   z
responses/é   Úuser)ÚappendÚsplitÚlitellmÚopen_ai_chat_completion_modelsÚopen_ai_text_completion_models)rA   rS   Úbase_paramsÚmodel_specific_paramsÚmodel_for_checks        rK   Úget_supported_openai_paramsz+OpenAIGPTConfig.get_supported_openai_params‡   s�   € ò
ˆðB (*ÐØÐ'Ò'¨E°WÒ,<Ø!×(Ñ(Ð):Ô;ð EQÐTYÑDY §¡¨\¸1Ó!=¸aÒ!@Ð_dˆàœw×EÑEÑEØ¤× FÑ FÑFØ!×(Ñ(Øôð Ð2Ñ2Ð2rM   Únon_default_paramsÚoptional_paramsÚdrop_paramsc                 ól   — | j                  |«      }|j                  «       D ]  \  }}||v sŒ|||<   Œ |S )aÃ  
        If any supported_openai_params are in non_default_params, add them to optional_params, so they are use in API call

        Args:
            non_default_params (dict): Non-default parameters to filter.
            optional_params (dict): Optional parameters to update.
            model (str): Model name for parameter support check.

        Returns:
            dict: Updated optional_params with supported non-default parameters.
        )rs   rD   )rA   rt   ru   rS   rv   Úsupported_openai_paramsÚparamrJ   s           rK   Ú_map_openai_paramsz"OpenAIGPTConfig._map_openai_params·   sL   € ð$ *.×)IÑ)IÈ%Ó)PÐØ.×4Ñ4Ó6ò 	/‰LˆE�5ØÐ/Ò/Ø).� Ò&ð	/ð ÐrM   c                 ó,   — | j                  ||||¬«      S )N)rt   ru   rS   rv   )rz   )rA   rt   ru   rS   rv   s        rK   Úmap_openai_paramsz!OpenAIGPTConfig.map_openai_paramsÏ   s(   € ð ×&Ñ&Ø1Ø+ØØ#ð	 'ó 
ð 	
rM   Úcontent_itemc                 ó^   ‡— g d¢}|j                  d«      Š‰rt        ˆfd„|D «       «      ryy)N)zhttps://zhttp://zwww.Úfile_idc              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrO   )Ú
startswith)Ú.0Ústartr   s     €rK   ú	<genexpr>z3OpenAIGPTConfig.contains_pdf_url.<locals>.<genexpr>à   s   øè ø€ Ò[¸˜7×-Ñ-¨e×4Ñ[ùs   ƒTF)ÚgetÚany)rA   r}   Úpotential_pdf_url_startsr   s      @rK   Úcontains_pdf_urlz OpenAIGPTConfig.contains_pdf_urlÝ   s0   ø€ Ú*IÐ Ø%×)Ñ)¨)Ó4ˆÙ”sÓ[ÐBZÔ[Ô[ØØrM   c                 ó˜   — |j                  «       }|j                  d«      }|�&t        |«      }||d<   d|d<   |j                  d«       |S ©Nr   Ú	file_dataúmy_file.pdfÚfilename)rC   r…   r   Úpop)rA   r}   Úcontent_copyr   Úbase64_datas        rK   Ú_handle_pdf_urlzOpenAIGPTConfig._handle_pdf_urlä   sX   € Ø*×/Ñ/Ó1ˆØ%×)Ñ)¨)Ó4ˆØÐÜ!6°wÓ!?ˆKØ(3ˆL˜Ñ%Ø'4ˆL˜Ñ$Ø×Ñ˜YÔ'ØÐrM   c              ƒ   ó”   K  — |j                  d«      }|�.t        |«      ƒ d {  –—† }||d<   d|d<   |j                  d«       |S 7 Œ!­wrŠ   )r…   r   rŽ   )rA   r}   r   r�   s       rK   Ú_async_handle_pdf_urlz%OpenAIGPTConfig._async_handle_pdf_urlî   sW   è ø€ Ø%×)Ñ)¨)Ó4ˆØÐÜ'BÀ7Ó'K×!KˆKØ(3ˆL˜Ñ%Ø'4ˆL˜Ñ$Ø×Ñ˜YÔ'ØÐð	 "Lús   ‚"A¤A¥"Ac                 ó\   — |j                  d«      }|j                  d«      }|�|€d|d<   |S )Nr‹   r�   rŒ   ©r…   )rA   r}   r‹   r�   s       rK   Ú_common_file_data_checkz'OpenAIGPTConfig._common_file_data_check÷   s=   € Ø'×+Ñ+¨KÓ8ˆ	Ø&×*Ñ*¨:Ó6ˆØÐ  XÐ%5Ø'4ˆL˜Ñ$ØÐrM   c           
      óT  — dh}|j                  d«      dk(  r~t        t        |«      }t        |d   t        «      rd|d   i|d<   |S t        |d   t
        «      r:t        d	i |d   j                  «       D ��ci c]  \  }}||vsŒ||“Œ c}}¤Ž}||d<   |S |j                  d«      dk(  rrt        t        |«      }|j                  d«      }|€t        j                  dd d¬«      ‚t        d	i |j                  «       D ��ci c]  \  }}||vsŒ||“Œ c}}¤Ž}||d<   |S c c}}w c c}}w )
NÚformatÚtypeÚ	image_urlÚurlÚfilezFContent block has type='file' but is missing the required 'file' fieldÚopenai)ÚmessagerS   Úllm_provider© )r…   r   r   Ú
isinstanceÚstrÚdictr    rD   r   rm   ÚBadRequestErrorr   )rA   r}   Úlitellm_specific_paramsÚkÚvÚnew_image_url_objÚfile_objÚnew_file_objs           rK   Ú$_apply_common_transform_content_itemz4OpenAIGPTConfig._apply_common_transform_content_itemþ   sb  € ð +3¨ÐØ×Ñ˜FÓ# {Ò2ÜÔ 9¸<ÓHˆLÜ˜, {Ñ3´SÔ9à˜<¨Ñ4ð-�˜[Ñ)ð, Ðô' ˜L¨Ñ5´tÔ<Ü+Gñ ,Ø(4°[Ñ(A×(GÑ(GÓ(I×n¡  1ÈQÐVmÒMm�q˜!‘tÓnñ,Ð!ð ->�˜[Ñ)ð Ðð ×Ñ˜fÓ%¨Ò/ÜÔ 8¸,ÓGˆLØ*×.Ñ.¨vÓ6ˆHØÐÜ×-Ñ-ØdØØ!)ôð ô
 #?ñ #Ø$,§N¡NÓ$4×Y™D˜A˜q¸ÐAXÒ8X�1�a‘4ÓYñ#ˆLð $0ˆL˜Ñ àÐùó# oùó Zs   Á7DÂDÃ?D$ÄD$c                 ó.  — | j                  |«      }|j                  d«      }|j                  d«      }|dk(  r\|rZt        t        |«      }t        t        |«      }| j                  |«      r| j                  |«      }| j                  |«      }||d<   |}|S ©Nr™   rœ   )r«   r…   r   r   r   rˆ   r‘   r–   )rA   r}   Úcontent_item_typeÚpotential_file_objr©   Úcontent_item_typeds         rK   Ú_transform_content_itemz'OpenAIGPTConfig._transform_content_item  s¡   € ð ×@Ñ@ÀÓNˆØ#/×#3Ñ#3°FÓ#;ÐØ$0×$4Ñ$4°VÓ$<ÐØ Ò&Ñ+=ÜÔ8Ð:LÓMˆHÜ(,Ô-EÀ|Ó(TÐØ×$Ñ$ XÔ.Ø×/Ñ/°Ó9�Ø×3Ñ3°HÓ=ˆHØ)1Ð˜vÑ&Ø-ˆLØÐrM   FÚis_asyncc              ƒ   óJ  K  — | j                  |«      }|j                  d«      }|j                  d«      }|dk(  rd|rbt        t        |«      }t        t        |«      }| j                  |«      r| j                  |«      ƒ d {  –—† }| j                  |«      }||d<   |}|S 7 Œ­wr­   )r«   r…   r   r   r   rˆ   r“   r–   )rA   r}   r²   r®   r¯   r©   r°   s          rK   Ú_async_transform_content_itemz-OpenAIGPTConfig._async_transform_content_item/  s®   è ø€ ð ×@Ñ@ÀÓNˆØ#/×#3Ñ#3°FÓ#;ÐØ$0×$4Ñ$4°VÓ$<ÐØ Ò&Ñ+=ÜÔ8Ð:LÓMˆHÜ(,Ô-EÀ|Ó(TÐØ×$Ñ$ XÔ.Ø!%×!;Ñ!;¸HÓ!E×E�Ø×3Ñ3°HÓ=ˆHØ)1Ð˜vÑ&Ø-ˆLØÐð	 Fús   ‚B B#ÂB!ÂB#Úmessagesc                  ó   — y rO   r    ©rA   rµ   rS   r²   s       rK   Ú_transform_messagesz#OpenAIGPTConfig._transform_messagesA  s   € ð 	rM   c                  ó   — y rO   r    r·   s       rK   r¸   z#OpenAIGPTConfig._transform_messagesG  s   € ð 	rM   c                 ór  ‡ ‡— t        |«      }t        |«      Šˆˆ fd„}|r |«       S ‰D ]Š  }|j                  d«      }|j                  d«      }|dk(  sŒ+|sŒ.t        |t        «      sŒ?t        t        t           |«      }	t        |«      D ]'  \  }
}‰ j                  t        t        |«      «      |	|
<   Œ) ŒŒ ‰S )zSOpenAI no longer supports image_url as a string, so we need to convert it to a dictc               “   óB  •K  — ‰D ]’  } | j                  d«      }| j                  d«      }|dk(  sŒ+|sŒ.t        |t        «      sŒ?t        t        t           |«      }t        |«      D ]/  \  }}‰j                  t        t        |«      «      ƒ d {  –—† ||<   Œ1 Œ” ‰S 7 Œ­w)NÚcontentÚrolerj   )r…   r¡   Úlistr   r"   Ú	enumerater´   )rž   Úmessage_contentÚmessage_roleÚmessage_content_typesÚir}   Úhoisted_messagesrA   s         €€rK   Ú_async_transformz=OpenAIGPTConfig._transform_messages.<locals>._async_transformY  s¦   øè ø€ Ø+ò 	�Ø")§+¡+¨iÓ"8�Ø&Ÿ{™{¨6Ó2�à 6Ó)ªoÄ*È_Ô^bÕBcÜ,0´Ô6SÑ1TÐVeÓ,fÐ)Ü+4Ð5JÓ+Kò ™˜˜<Ø9=×9[Ñ9[Ü Ô!>ÀÓMó:÷ 4Ð-¨aÒ0ñð	ð $Ð#ð4ús"   ƒ-B±B´BÁA
BÂBÂBr¼   r½   rj   )	r   r   r…   r¡   r¾   r   r"   r¿   r±   )rA   rµ   rS   r²   Ústripped_messagesrÅ   rž   rÀ   rÁ   rÂ   rÃ   r}   rÄ   s   `           @rK   r¸   z#OpenAIGPTConfig._transform_messagesR  sÅ   ù€ ô $PÐPXÓ#YÐÜ"AÐBSÓ"TÐõ	$ñ Ù#Ó%Ð%à+ò �Ø")§+¡+¨iÓ"8�Ø&Ÿ{™{¨6Ó2�Ø 6Ó)ªoÄ*È_Ô^bÕBcÜ,0´Ô6SÑ1TÐVeÓ,fÐ)Ü+4°_Ó+Eò ™˜˜<Ø37×3OÑ3OÜ Ô!>ÀÓMó4Ð-¨aÒ0ñðð $Ð#rM   r]   r1   c                 óÒ   — ddl m} ddlm} t	        |«      D ]  \  }}t        t         ||d«      «      ||<   Œ! |�)t	        |«      D ]  \  }}t        | ||d«      «      ||<   Œ ||fS )Nr   )Úfilter_value_from_dictr0   Úcache_control)Ú8litellm.litellm_core_utils.prompt_templates.common_utilsrÈ   Úlitellm.types.llms.openair1   r¿   r   r   )	rA   rS   rµ   r]   rÈ   r1   rÃ   rž   Útools	            rK   Ú1remove_cache_control_flag_from_messages_and_toolszAOpenAIGPTConfig.remove_cache_control_flag_from_messages_and_toolst  s‡   € õ	
õ 	Fä# HÓ-ò 	‰JˆAˆwÜÜ Ù& w°Ó@óˆH�QŠKð	ð
 ÐÜ$ UÓ+ò ‘��4ÜØ+Ù*¨4°ÓAó��a’ðð
 ˜ˆÐrM   Úcustom_llm_providerÚapi_basec                 óú   — |dk7  ry|xs> t         j                  xs, t        j                  d«      xs t        j                  d«      }|syt	        |«      j
                  }|€y|dk7  xr |j                  d«       S )aB  
        The generic `openai` provider also reaches OpenAI-compatible endpoints
        (a LiteLLM proxy, vLLM, an Anthropic-compatible gateway) via a custom
        api_base. Those can understand cache_control, so it must survive there.
        Real OpenAI cannot, so it is still stripped for an openai.com host.
        r�   FÚOPENAI_BASE_URLÚOPENAI_API_BASEz
openai.comz.openai.com)rm   rÏ   ÚosÚgetenvr   ÚhostnameÚendswith)rA   rÎ   rÏ   Úresolved_api_baserÕ   s        rK   Ú+_should_preserve_cache_control_for_endpointz;OpenAIGPTConfig._should_preserve_cache_control_for_endpointŒ  s   € ð  (Ò*ØØ$Òx¬×(8Ñ(8Òx¼B¿I¹IÐFWÓ<XÒxÔ\^×\eÑ\eÐfwÓ\xÐÙ ØÜ"Ð#4Ó5×>Ñ>ˆØÐØØ˜<Ñ'ÒP°×0AÑ0AÀ-Ó0PÐ,PÐPrM   Úlitellm_paramsÚheadersc                 ó2  — | j                  ||¬«      }| j                  |j                  d«      |j                  d«      «      s<| j                  |||j                  dg «      ¬«      \  }}|�t	        |«      dkD  r||d<   |j                  dd«       ||d	œ|¥S )
z¥
        Transform the overall request to be sent to the API.

        Returns:
            dict: The transformed request. Sent as the body of the API call.
        )rµ   rS   rÎ   rÏ   r]   ©rS   rµ   r]   Nr   r_   ©rS   rµ   )r¸   rØ   r…   rÍ   ÚlenrŽ   )rA   rS   rµ   ru   rÙ   rÚ   r]   s          rK   Útransform_requestz!OpenAIGPTConfig.transform_request¡  s¼   € ð ×+Ñ+°XÀUÐ+ÓKˆØ×?Ñ?Ø×ÑÐ4Ó5°~×7IÑ7IÈ*Ó7Uô
ð #×TÑTØ h°o×6IÑ6IÈ'ÐSUÓ6Vð Uó ‰OˆH�eð Ð ¤S¨£Z°!¢^Ø+0� Ñ(à×Ñ˜M¨4Ô0ð Ø ñ
ð ð
ð 	
rM   c              ƒ   ó‚  K  — | j                  ||d¬«      ƒ d {  –—† }| j                  |j                  d«      |j                  d«      «      s<| j                  |||j                  dg «      ¬«      \  }}|�t	        |«      dkD  r||d<   | j
                  j                  r||dœ|¥S | j                  |||||«      S 7 Œ¢­w)	NT)rµ   rS   r²   rÎ   rÏ   r]   rÜ   r   rÝ   )r¸   rØ   r…   rÍ   rÞ   rF   rG   rß   )rA   rS   rµ   ru   rÙ   rÚ   Útransformed_messagesr]   s           rK   Úasync_transform_requestz'OpenAIGPTConfig.async_transform_requestÁ  së   è ø€ ð &*×%=Ñ%=ÀxÐW\ÐgkÐ%=Ó%l×lÐØ×?Ñ?Ø×ÑÐ4Ó5°~×7IÑ7IÈ*Ó7Uô
ð ×FÑFØØ-Ø%×)Ñ)¨'°2Ó6ð Gó ñØ$Øð Ð ¤S¨£Z°!¢^Ø+0� Ñ(Ø�>‰>×(Ò(àØ0ñð "ðð ð ×)Ñ)¨%°¸?ÈNÐ\cÓdÐdð-  mús   ‚B?šB=›B#B?c                 ó*   — |j                  dd «      d uS )Nr]   r•   )rA   ru   s     rK   Ú_passed_in_toolsz OpenAIGPTConfig._passed_in_toolsá  s   € Ø×"Ñ" 7¨DÓ1¸Ð=Ð=rM   r¼   c                 ób  — ddl }| j                  |«      syt        |j                  dg «      «      }	  |j                  |«      }|j                  d«      dk(  rH|j                  d«      |v r5t        t        |j                  d«      |j                  d«      ¬«      ¬	«      S y# t        $ r Y yw xY w)
z5
        Check if the content is a tool call
        r   Nr]   r™   ÚfunctionÚnameÚ	arguments)rç   rè   )ræ   )Újsonrä   r   r…   Úloadsr$   r&   Ú	Exception)rA   r¼   ru   ré   Útool_call_namesÚjson_contents         rK   Ú&_check_and_fix_if_content_is_tool_callz6OpenAIGPTConfig._check_and_fix_if_content_is_tool_callä  sµ   € ó 	à×$Ñ$ _Ô5ØÜ!4°_×5HÑ5HÈÐRTÓ5UÓ!Vˆð
	Ø", $§*¡*¨WÓ"5ˆLØ×Ñ Ó'¨:Ò5¸,×:JÑ:JÈ6Ó:RÐVeÑ:eÜ4Ü%Ø)×-Ñ-¨fÓ5Ø".×"2Ñ"2°;Ó"?ôôð ð øô ò 	Ùð	ús   ³A-B" Â"	B.Â-B.rž   Úreceived_finish_reasonc                 ó    — |j                   �y|S )NÚ
tool_calls)rñ   )rA   rž   rï   s      rK   Ú_get_finish_reasonz"OpenAIGPTConfig._get_finish_reasoný  s   € Ø×ÑÐ)Øà)Ð)rM   ÚchoicesÚ	json_modec                 óÖ  — g }|D �]`  }|d   j                  dd «      }d }|d   j                  dd «      }|�5g }	|D ]  }
t        |
«      }|	j                  |«       Œ  t        |	«      }|�6|}n3|�1|r/t	        |t
        «      r| j                  ||«      }|�d |d   d<   |g}d }d }|rBt        ||¬«      r5t        |d   d   j                  dd«      «      xs d }|�t        |¬	«      }d
}|€/t        t        t        |d   «      «      \  }}t        d||d |¬«      }|€|d   }t        ||d   |d d ¬«      }t        | j                  ||d   «      «      |_        |j                  |«       �Œc |S )Nrž   rñ   r¼   )rñ   Úconvert_tool_call_to_json_moder   ræ   rè   Ú )r¼   r;   Ú	assistant)r½   r¼   Úreasoning_contentÚthinking_blocksrñ   Úfinish_reasonÚindex)rû   rü   rž   rU   Úenhancements)r…   r*   rk   r   r¡   r¢   rî   r   r'   r   r   r£   r%   r   rò   rû   )rA   ró   rô   ru   Útransformed_choicesÚchoicerñ   Únew_tool_callsrÀ   Ú_openai_tool_callsÚ_tcÚ
_openai_tcÚfixed_tool_callsÚnew_tool_callÚtranslated_messagerû   Újson_mode_content_strrù   Úcontent_strÚtranslated_choices                       rK   Ú_transform_choicesz"OpenAIGPTConfig._transform_choices  sô  € ð &(Ðàó ?	:ˆFà 	Ñ*×.Ñ.¨|¸TÓBˆJàð ð % YÑ/×3Ñ3°I¸tÓDˆOØÐ%Ø%'Ð"Ø%ò :�CÜ!DÀSÓ!I�JØ&×-Ñ-¨jÕ9ð:ô $GÐGYÓ#ZÐ à#Ð/Ø%5‘NØ Ð,±ÄZÐP_ÔadÔEeØ $× KÑ KÈOÐ]lÓ m�Ø Ð,Ø37�F˜9Ñ% iÑ0Ø&3 _�Nà15ÐØ(,ˆMÙÔ"HØ)Ø/8õ#ô
 58¸ÀqÑ8IÈ*Ñ8U×8YÑ8YÐZeÐgiÓ8jÓ4kÒ4sÐosÐ%Ø(Ð4Ü)0Ð9NÔ)OÐ&Ø$*�Mà!Ð)ô
 /¬t´D¸&ÀÑ:KÓ/LÓMñØ%Øô &-Ø$Ø'Ø&7Ø$(Ø-ô&Ð"ð Ð$Ø & Ñ 7�ä 'Ø+Ø˜W‘oØ*ØØ!ô!Ðô /@Ø×'Ñ'Ð(:¸FÀ?Ñ<SÓTó/ÐÔ+ð  ×&Ñ&Ð'8Ö9ð?	:ðB #Ð"rM   Úraw_responseÚmodel_responseÚlogging_objÚrequest_dataÚencodingztiktoken.Encoding | NoneÚapi_keyc                 ó^  — |j                  ||
|j                  d|i¬«       	 |j                  «       }t        |j                  «      }t        ||d|i|¬«      }t        t        |«      S # t        $ r:}t	        |dd«      }t        d|› d|j                  › �|j                  |¬«      ‚d}~ww xY w)	zt
        Transform the response from the API.

        Returns:
            dict: The transformed response.
        Úcomplete_input_dict)Úinputr  Úoriginal_responseÚadditional_argsrÚ   NzUnable to get json response - z, Original Response: )rž   Ústatus_coderÚ   )Úresponse_objectÚmodel_response_objectÚhidden_paramsÚ_response_headers)Ú	post_callÚtextré   rë   Úgetattrr-   r  r£   rÚ   r+   r   r(   )rA   rS   r  r  r  r  rµ   ru   rÙ   r  r  rô   Úcompletion_responseÚeÚresponse_headersÚraw_response_headersÚfinal_response_objs                    rK   Útransform_responsez"OpenAIGPTConfig.transform_responseN  sÕ   € ð, 	×ÑØØØ*×/Ñ/Ø2°LÐAð	 	ô 	
ð	Ø)5×):Ñ):Ó)<Ðô '+¨<×+?Ñ+?Ó&@ÐÜ$DØ/Ø"0Ø$Ð&:Ð;Ø2ô	%
Ðô ”MÐ#5Ó6Ð6øô ò 	Ü&-¨l¸IÀtÓ&LÐÜØ8¸¸Ð;PÐQ]×QbÑQbÐPcÐdØ(×4Ñ4Ø(ôð ûð	ús   £A) Á)	B,Á25B'Â'B,Úerror_messager  c                 óN   — t        ||t        t        j                  |«      ¬«      S )N)r  rž   rÚ   )r-   r   ÚhttpxÚHeaders)rA   r$  r  rÚ   s       rK   Úget_error_classzOpenAIGPTConfig.get_error_class  s#   € ÜØ#Ø!ÜœŸ™¨Ó0ô
ð 	
rM   r[   c                 óJ   — |€d}d}|j                  d«      }||v r|S |› d|› �S )z~
        Get the complete URL for the API call.

        Returns:
            str: The complete URL for the API call.
        úhttps://api.openai.comzchat/completionsú/)Úrstrip)rA   rÏ   r  rS   ru   rÙ   r[   Úendpoints           rK   Úget_complete_urlz OpenAIGPTConfig.get_complete_url†  sD   € ð ÐØ/ˆHØ,ˆð —?‘? 3Ó'ˆð �xÑØˆOà�˜1˜X˜JÐ'Ð'rM   c                 ó4   — |�d|› �|d<   d|vr	d|vrd|d<   |S )NúBearer ÚAuthorizationzcontent-typezContent-Typezapplication/jsonr    )rA   rÚ   rS   rµ   ru   rÙ   r  rÏ   s           rK   Úvalidate_environmentz$OpenAIGPTConfig.validate_environment¢  s;   € ð ÐØ)0°°	Ð':ˆG�OÑ$ð  Ñ(¨^À7Ñ-JØ&8ˆG�NÑ#àˆrM   c                 ó¶  — |€d}|€t        d«      }t        j                  |«      }|j                  › d|j                  › �}|j
                  r|d|j
                  › �z  }t        j                  j                  |› d�dd|› �i¬«      }|j                  d	k7  rt        d
|j                  › �«      ‚|j                  «       d   }|D �cg c]  }|d   ‘Œ	 c}S c c}w )zV
        Calls OpenAI's `/v1/models` endpoint and returns the list of models.
        r*  ÚOPENAI_API_KEYz://ú:z
/v1/modelsr1  r0  )r›   rÚ   éÈ   zFailed to get models: ÚdataÚid)r   r&  ÚURLÚschemeÚhostÚportrm   Úmodule_level_clientr…   r  rë   r  ré   )rA   r  rÏ   Ú
parsed_urlÚbase_urlÚresponseÚmodelsrS   s           rK   Ú
get_modelszOpenAIGPTConfig.get_modelsµ  së   € ð
 ÐØ/ˆHØˆ?Ü$Ð%5Ó6ˆGô "ŸI™I hÓ/ˆ
Ø ×'Ñ'Ð(¨¨J¯O©OÐ+<Ð=ˆØ�?Š?Ø˜!˜JŸO™OÐ,Ð-Ñ-ˆHä!×5Ñ5×9Ñ9Ø�*˜JÐ'Ø$¨°¨yÐ&9Ð:ð :ó 
ˆð
 ×Ñ 3Ò&ÜÐ4°X·]±]°OÐDÓEÐEà Ÿ™›¨Ñ/ˆØ)/Ö0 ��d“Ò0Ð0ùÒ0s   ÃCc                 óh   — | xs/ t         j                  xs t         j                  xs t        d«      S )Nr4  )rm   r  Ú
openai_keyr   )r  s    rK   Úget_api_keyzOpenAIGPTConfig.get_api_keyÐ  s'   € àÒcœ'Ÿ/™/Òc¬W×-?Ñ-?ÒcÄ>ÐRbÓCcÐcrM   c                 óf   — | xs. t         j                  xs t        d«      xs t        d«      xs dS )NrÑ   rÒ   zhttps://api.openai.com/v1)rm   rÏ   r   )rÏ   s    rK   Úget_api_basezOpenAIGPTConfig.get_api_baseÔ  sB   € ð ò +Ü×Ñò+äÐ/Ó0ò+ô Ð/Ó0ò+ð +ð	
rM   c                 ó   — | S rO   r    )rS   s    rK   Úget_base_modelzOpenAIGPTConfig.get_base_modelÞ  s   € àˆrM   r/   c                 ó   — ddl m}  |«       S )Nr   )ÚOpenAITokenCounter)Ú8litellm.llms.openai.responses.count_tokens.token_counterrK  )rA   rK  s     rK   Úget_token_counterz!OpenAIGPTConfig.get_token_counterâ  s   € õ	
ñ "Ó#Ð#rM   Ústreaming_responseÚsync_streamc                 ó   — t        |||¬«      S )N)rN  rO  rô   )Ú$OpenAIChatCompletionStreamingHandler)rA   rN  rO  rô   s       rK   Úget_model_response_iteratorz+OpenAIGPTConfig.get_model_response_iteratoré  s   € ô 4Ø1Ø#Øô
ð 	
rM   )NNNNNNNNNNN)FrO   )NN)MÚ__name__Ú
__module__Ú__qualname__Ú__doc__rG   r4   ÚintÚ__annotations__r5   r¢   r£   r6   r¾   r7   r8   r9   r:   r;   r<   r=   r>   rL   ÚclassmethodrQ   rs   Úboolrz   r|   r   rˆ   r‘   r“   r–   r"   r«   r±   r´   r   r   r	   r   r   r¸   ÚtuplerÍ   rØ   rß   râ   rä   r$   rî   r'   rò   r!   r%   r
  r&  ÚResponser(   ÚLiteLLMLoggingObjr#  r'  r   r(  r.  r2  rB  ÚstaticmethodrE  rG  rI  r
   rM  r   r   rR  Ú__classcell__)rF   s   @rK   r3   r3   D   só  ø… ñð6 €Nà$(Ð�s˜T‘zÓ(Ø'+€M�3˜‘: Ñ$Ó+Ø!€Iˆt�d‰{Ó!Ø"€J��t‘Ó"Ø!€J��d‘
Ó!Ø€A€sˆT�zÓØ#'Ð�c˜D‘jÓ'Ø"€Dˆ#�‰*�tÑ
Ó"Ø"€K��t‘Ó"Ø€Eˆ3�‰:ÓØ#'€O�T˜D‘[Ó'ð )-Ø+/Ø!%Ø"&Ø!%ØØ'+Ø"&Ø"&Ø Ø'+ñ.à ™:ð.ð ˜T‘z DÑ(ð.ð ˜$‘;ð	.ð
 ˜4‘Kð.ð ˜$‘Jð.ð �‰:ð.ð  ™*ð.ð �D‰j˜4Ñð.ð ˜4‘Zð.ð �T‰zð.ð  ™ð.ð 
ó.ð* ó$ó ð$ð.3°ð .3¸ó .3ð`à ðð ðð ð	ð
 ðð 
óð0
à ð
ð ð
ð ð	
ð
 ð
ð 
ó
ðÐ-Ið Èdó ðÐ,Hð ÐMió ðÐ8Tð ÐYuó ðÐ4Pð ÐUqó ðà3ðð 
'óð@à3ðð 
'óð$ MRñØ9ðØEIðà	&óð$ ðØÐ-Ñ.ðØ7:ðØFMÈdÁmðà	�3˜˜TÐ"2Ñ3Ð3Ñ	4òó ðð
 ð
 $)ñ	àÐ'Ñ(ðð ðð ˜%‘.ð	ð
 
ÐÑ	òó ðð NSñ $ØÐ-Ñ.ð $Ø7:ð $ØFJð $à	ÐÑ	 )¨C°°dÐ;KÑ6LÐ,LÑ"MÑ	Mó $ðL 9=ñ	àðð Ð'Ñ(ðð Ð-Ñ.°Ñ5ð	ð
 
ˆtÐ$Ñ% tÐ,EÑ'FÈÑ'MÐMÑ	Nóð0Qà  4™ZðQð ˜‘*ðQð 
ó	Qð*
àð
ð Ð'Ñ(ð
ð ð	
ð
 ð
ð ð
ð 
ó
ð@eàðeð Ð'Ñ(ðeð ð	eð
 ðeð ðeð 
óeð@>°ð >¸ó >ðØðØ-1ðà	&¨Ñ	-óð2*¨'ð *È3ð *ÐSVó *ð "&Ø'+ñ	I#àÐ1Ñ2ðI#ð ˜$‘;ðI#ð  ™ð	I#ð
 
ˆg‰óI#ðl #Ø!%ñ/7àð/7ð —n‘nð/7ð &ð	/7ð
 'ð/7ð ð/7ð Ð'Ñ(ð/7ð ð/7ð ð/7ð -ð/7ð �t‘ð/7ð ˜$‘;ð/7ð 
ó/7ðb
¨Sð 
¸sð 
ÈTÐTY×TaÑTaÑMað 
Ðfvó 
ð #ñ(à˜‘*ð(ð �t‘ð(ð ð	(ð
 ð(ð ð(ð �t‘ð(ð 
ó(ðF #Ø#ñàðð ðð Ð'Ñ(ð	ð
 ðð ðð �t‘ðð ˜‘*ðð 
óñ&1 #¨¡*ð 1¸sÀT¹zð 1ÐUYÐZ]ÑU^ó 1ð6 ñd˜S 4™Zð d°3¸±:ò dó ðdð ñ
˜s T™zð 
°S¸4±Zò 
ó ð
ð ñ˜c D™jð °C¸$±Jò ó ðð$ 8Ð,>Ñ#?ó $ð "'ñ	

à$ S™M¨M¸#Ñ,>Ñ>ÀÑNð

ð ð

ð ˜$‘;ð	

ð
 
÷

rM   r3   c                   óV   — e Zd Zdedefd„Zededeee	f   dz  fd„«       Z
dedefd„Zy)rQ  ró   r?   c                 ój   — |D ]-  }|j                  di «      }d|v sŒ|j                  d«      |d<   Œ/ |S )a“  
        Map 'reasoning' field to 'reasoning_content' field in delta.

        Some OpenAI-compatible providers (e.g., GLM-5, hosted_vllm) return
        delta.reasoning, but LiteLLM expects delta.reasoning_content.

        Args:
            choices: List of choice objects from the streaming chunk

        Returns:
            List of choices with reasoning field mapped to reasoning_content
        ÚdeltaÚ	reasoningrù   )r…   rŽ   )rA   ró   rÿ   rb  s       rK   Ú#_map_reasoning_to_reasoning_contentzHOpenAIChatCompletionStreamingHandler._map_reasoning_to_reasoning_content÷  sH   € ð ò 	DˆFØ—J‘J˜w¨Ó+ˆEØ˜eÒ#Ø-2¯Y©Y°{Ó-C�Ð)Ò*ð	Dð ˆrM   ÚchunkNc                 óB  — | j                  d«      }|syt        |t        «      st        |«      dfS |j                  d«      }|j                  d«      }t        |t        «      rd|cxk  rdk  rn n|nd}t        |t        «      r||fS t        j                  |«      |fS )z·OpenAI-compatible backends (vLLM, sglang) can return an HTTP 200
        stream whose body carries an error payload, e.g.
        ``data: {"error": {"message": "...", "code": 400}}``.ÚerrorNiô  rž   Úcodei�  iX  )r…   r¡   r£   r¢   rW  ré   Údumps)re  rg  rž   rh  r  s        rK   Ú_extract_error_from_chunkz>OpenAIChatCompletionStreamingHandler._extract_error_from_chunk
  s�   € ð
 —y‘y Ó)ˆÙØÜ˜%¤Ô&Ü�u“:˜s�?Ð"ØŸ™ 9Ó-ˆØ—i‘i Ó'ˆÜ%/°´cÔ%:¸sÀdÔ?PÈSÕ?P™TÐVYˆÜ% g¬sÔ3�È[ÐXÐX¼¿¹ÀEÓ9JÈ[ÐXÐXrM   c                 ó\  — 	 | j                  |«      }|�|\  }}t        ||¬«      ‚|j                  dg «      }| j                  |«      }|j                  d«      d|j                  d«      |j                  d«      |dœ}d|v r|d   �|d   |d<   t	        d	i |¤ŽS # t
        $ r}|‚d }~ww xY w)
N)r  rž   ró   r8  zchat.completion.chunkÚcreatedrS   )r8  Úobjectrl  rS   ró   Úusager    )rj  r-   r…   rd  r)   rë   )rA   re  Úerror_detailsr$  Úerror_status_coderó   Úkwargsr  s           rK   Úchunk_parserz1OpenAIChatCompletionStreamingHandler.chunk_parser  sÒ   € ð	Ø#'×#AÑ#AÀ%Ó#HˆMØÐ(Ø3@Ñ0�Ð0Ü!Ø 1Ø)ôð ð —i‘i 	¨2Ó.ˆGØ×>Ñ>¸wÓGˆGð —i‘i “oØ1Ø Ÿ9™9 YÓ/ØŸ™ 7Ó+Ø"ñ-ˆFð ˜%Ñ E¨'¡NÐ$>Ø"'¨¡.��w‘Ü&Ñ0¨Ñ0Ð0øÜò 	ØˆGûð	ús   ‚BB Â	B+Â$B&Â&B+)rS  rT  rU  r¾   rd  r^  r£   r[  r¢   rW  rj  r)   rr  r    rM   rK   rQ  rQ  ö  s\   „ ð¸4ð ÀDó ð& ðY¨ð Y°%¸¸S¸±/ÀDÑ2Hò Yó ðYð $ð Ð+>ô rM   rQ  )GrV  ré   rÓ   Úcollections.abcr   r   r   Útypingr   r   r   r	   r
   r   r   Úurllib.parser   r&  rm   Ú'litellm.litellm_core_utils.core_helpersr   ÚFlitellm.litellm_core_utils.llm_response_utils.convert_dict_to_responser   r   r   rÊ   r   r   r   Ú:litellm.litellm_core_utils.prompt_templates.image_handlingr   r   Ú)litellm.llms.base_llm.base_model_iteratorr   Ú litellm.llms.base_llm.base_utilsr   Ú)litellm.llms.base_llm.chat.transformationr   r   Úlitellm.secret_managers.mainr   rË   r   r   r   r   r    r!   r"   Úlitellm.types.utilsr#   r$   r%   r&   r'   r(   r)   r*   Úlitellm.utilsr+   Úcommon_utilsr-   ÚtiktokenÚ*litellm.litellm_core_utils.litellm_loggingr.   Ú_LiteLLMLoggingObjr/   r1   r]  r3   rQ  r    rM   rK   ú<module>rƒ     sµ   ðñó Û 	ß >Ñ >ß O× OÑ OÝ !ã ã Ý E÷ñ ÷
ñ ÷
õ PÝ =ß RÝ 7÷÷ ñ ÷	÷ 	ó 	õ ;å &áÛåXÝAÝAà*ÑàÐôo

Ð&¨
ô o

ôd:Ð+Dõ :rM   