
    j}                          d dl mZmZmZ d dlZd dlZd dl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mZmZ dd	lmZ d
Z G d de      Zy)    )ListOptionalTupleN)verbose_logger)filter_value_from_dictstrip_name_from_messages)get_secret_str)AllMessageValues)ChoicesModelResponseUsagePromptTokensDetailsWrapper   )OpenAIGPTConfigzhttps://api.x.ai/v1c                   n    e Zd Zedee   fd       Zdee   dee   deee   ee   f   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d
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 fdZededdfd       Z	 	 ddedej.                  dededee   dededee   dee   def fdZdededdfdZ xZS )XAIChatConfigreturnc                      y)Nxai )selfs    }/Users/manta/Documents/Projects/TheRoad-I1/backend/.venv/lib/python3.12/site-packages/litellm/llms/xai/chat/transformation.pycustom_llm_providerz!XAIChatConfig.custom_llm_provider   s        api_baseapi_keyc                 V    |xs t        d      xs t        }|xs t        d      }||fS )NXAI_API_BASEXAI_API_KEY)r	   r   )r   r   r   dynamic_api_keys       r   $_get_openai_compatible_provider_infoz2XAIChatConfig._get_openai_compatible_provider_info   s2     M~n=M!B^M%B((r   modelc                 Z   g d}| j                  |      r|j                  d       | j                  |      r|j                  d       	 t        j                  || j
                        r|j                  d       |S # t        $ r#}t        j                  d|        Y d }~|S d }~ww xY w)N)
logit_biaslogprobs
max_tokensnpresence_penaltyresponse_formatseedstreamstream_optionstemperaturetool_choicetoolstop_logprobstop_puserweb_search_optionsstopfrequency_penalty)r"   r   reasoning_effortz,Error checking if model supports reasoning: )	_supports_stop_reasonappend_supports_frequency_penaltylitellmsupports_reasoningr   	Exceptionr   debug)r   r"   base_openai_paramses       r   get_supported_openai_paramsz)XAIChatConfig.get_supported_openai_params    s    
, %%e,%%f- ++E2%%&9:
	U))1I1I #))*<= "!  	U  #OPQs!STT!!	Us   
2A> >	B*B%%B*c                 "    d|v ryd|v ryd|v ryy)Nzgrok-3-miniFgrok-4grok-code-fastTr   r   r"   s     r   r7   z#XAIChatConfig._supports_stop_reasonN   s&    E!&r   c                     d|v ryd|v ryy)z
        From manual testing grok-4 does not support `frequency_penalty`

        When sent the model fails from xAI API
        rB   FrC   Tr   rD   s     r   r9   z)XAIChatConfig._supports_frequency_penaltyW   s     uu$r   non_default_paramsoptional_paramsdrop_paramsc                    | j                  |      }|j                         D ]b  \  }}|dk(  r||d<   |dk(  r@|>g }|D ]"  }	t        |	d      }	|	|j                  |	       $ t	        |      dkD  sP||d<   V||v s[|^|||<   d |S )N)r"   max_completion_tokensr&   r/   strictr   )r@   itemsr   r8   len)
r   rF   rG   r"   rH   supported_openai_paramsparamvaluer/   tools
             r   map_openai_paramszXAIChatConfig.map_openai_paramsc   s     #'"B"B"B"O.446LE5//05-'!e&7!D1$AD'T* " u:>/4OG,11$-2OE* 7 r   messageslitellm_paramsheadersc                 @    t        |      }t        | 	  |||||      S )zp
        Handle https://github.com/BerriAI/litellm/issues/9720

        Filter out 'name' from messages
        )r   supertransform_request)r   r"   rS   rG   rT   rU   	__class__s         r   rX   zXAIChatConfig.transform_request{   s,     ,H5w(8_ng
 	
r   choiceNc                     | j                   dk(  rB| j                  j                  r+t        | j                  j                        dkD  rd| _         yyyy)z
        Helper to fix finish_reason for tool calls when XAI API returns empty string.
        
        XAI API returns empty string for finish_reason when using tools,
        so we need to set it to "tool_calls" when tool_calls are present.
         r   
tool_callsN)finish_reasonmessager]   rM   )rZ   s    r   (_fix_choice_finish_reason_for_tool_callsz6XAIChatConfig._fix_choice_finish_reason_for_tool_calls   sM       B&NN%%))*Q.#/F  / & 'r   raw_responsemodel_responserequest_data	json_modec                 ^   t         |   |||||||||	|
|      }|j                  r3|j                  D ]$  }t        |t              s| j                  |       & 	 |j                         }| j                  ||       |S # t        $ r#}t        j                  d|        Y d}~|S d}~ww xY w)a2  
        Transform the response from the XAI API.
        
        XAI API returns empty string for finish_reason when using tools,
        so we need to fix this after the standard OpenAI transformation.
        
        Also handles X.AI web search usage tracking by extracting num_sources_used.
        )r"   ra   rb   logging_objrc   rS   rG   rT   encodingr   rd   z(Error extracting X.AI web search usage: N)rW   transform_responsechoices
isinstancer   r`   json)_enhance_usage_with_xai_web_search_fieldsr<   r   r=   )r   r"   ra   rb   rf   rc   rS   rG   rT   rg   r   rd   responserZ   raw_response_jsonr?   rY   s                   r   rh   z XAIChatConfig.transform_response   s    0 7-%)#%+) . 
 "**fg.AA&I +
	Q , 1 1 3::8EVW   	Q  #KA3!OPP	Qs   "B   	B,	B''B,rn   c                    t        |d      r|j                  y|j                  }d}|j                  di       }t        |t              rd|v r|j                  d      }|j|dkD  rd|j
                  t               |_        t        |      |j
                  _        t        |dt        |             t        j                  d|        yyy)z`
        Extract num_sources_used from X.AI response and map it to web_search_requests.
        usageNnum_sources_usedr   zX.AI web search sources used: )hasattrrp   getrj   dictprompt_tokens_detailsr   intweb_search_requestssetattrr   r=   )r   rb   rn   rp   rq   response_usages         r   rl   z7XAIChatConfig._enhance_usage_with_xai_web_search_fields   s     ~w/>3G3G3O%++*..w;nd+0Bn0T-112DE ',<q,@**2.H.J+>ABR>SE'';E-s3C/DE  #ABRAS!TU -A'r   )F)NN)__name__
__module____qualname__propertyr   strr   r   r!   listr@   boolr7   r9   rt   rR   r   r
   rX   staticmethodr   r`   httpxResponser   rh   rl   __classcell__)rY   s   @r   r   r      s   Xc]  ) )08)	x}hsm+	,)," ," ,"\3 4 
 
 
" "   	
  
0

 '(
 	

 
 
 

$ 
0 
0T 
0 
0. "&$(22 nn2 &	2 2 '(2 2 2 #2 D>2 
2hV+V@DV	Vr   r   )typingr   r   r   r   r:   litellm._loggingr   8litellm.litellm_core_utils.prompt_templates.common_utilsr   r   litellm.secret_managers.mainr	   litellm.types.llms.openair
   litellm.types.utilsr   r   r   r   openai.chat.gpt_transformationr   r   r   r   r   r   <module>r      s?    ( (   + 8 6 Y Y =$PVO PVr   