
    jw.                         d Z ddlZ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mZmZ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)z 
Support for Snowflake REST API
    N)TYPE_CHECKINGAnyDictListOptionalTupleUnionget_secret_str)AllMessageValues)ChatCompletionMessageToolCallFunctionModelResponse   )OpenAIGPTConfig)Loggingc                   6    e Zd ZdZe fd       Zdedee   fdZde	de	dede
de	f
d	Zd
eeeef      deeeee      f   fdZ	 	 d!dedej&                  dedede	dee   de	de	dedee   dee
   defdZ	 	 d!de	dedee   de	de	dee   dee   de	fdZdee   dee   deee   ee   f   fdZ	 d"dee   dee   dede	de	dee
   defdZdeeeef      deeeef      fdZdeeeeef   f   deeeeef   f   fdZdedee   de	de	de	de	fd Z xZS )#SnowflakeConfiga.  
    Reference: https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-llm-rest-api

    Snowflake Cortex LLM REST API supports function calling with specific models (e.g., Claude 3.5 Sonnet).
    This config handles transformation between OpenAI format and Snowflake's tool_spec format.
    c                      t         |          S N)super
get_config)cls	__class__s    /Users/manta/Documents/Projects/TheRoad-I1/backend/.venv/lib/python3.12/site-packages/litellm/llms/snowflake/chat/transformation.pyr   zSnowflakeConfig.get_config    s    w!##    modelreturnc                 
    g dS )N)temperature
max_tokenstop_presponse_formattoolstool_choice )selfr   s     r   get_supported_openai_paramsz+SnowflakeConfig.get_supported_openai_params$   s    
 	
r   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 used 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.
        )r(   items)r'   r)   r*   r   r+   supported_openai_paramsparamvalues           r   map_openai_paramsz!SnowflakeConfig.map_openai_params.   sG    $ #'"B"B5"I.446LE5//).& 7 r   content_listc                    d}g }t        |      D ]  \  }}|j                  d      dk(  r||j                  dd      z  }0|j                  d      dk(  sE|j                  di       }t        |j                  dd      dt        |j                  dd      t	        j
                  |j                  di             	      
      }|j                  |        ||r|fS dfS )a  
        Transform Snowflake tool calls to OpenAI format.

        Args:
            content_list: Snowflake's content_list array containing text and tool_use items

        Returns:
            Tuple of (text_content, tool_calls)

        Snowflake format in content_list:
        {
          "type": "tool_use",
          "tool_use": {
            "tool_use_id": "tooluse_...",
            "name": "get_weather",
            "input": {"location": "Paris"}
          }
        }

        OpenAI format (returned tool_calls):
        ChatCompletionMessageToolCall(
            id="tooluse_...",
            type="function",
            function=Function(name="get_weather", arguments='{"location": "Paris"}')
        )
         typetexttool_usetool_use_idfunctionnameinput)r:   	arguments)idr5   r9   N)	enumerategetr   r   jsondumpsappend)r'   r2   text_content
tool_callsidxcontent_itemtool_use_data	tool_calls           r   ._transform_tool_calls_from_snowflake_to_openaiz>SnowflakeConfig._transform_tool_calls_from_snowflake_to_openaiF   s    : :<
!*<!8C'61 0 0 << !!&)Z7 , 0 0R @9$((;#%*..vr:"&**]->->w-K"L	 !!), "9" :Z??4??r   raw_responsemodel_responselogging_objrequest_datamessageslitellm_paramsencodingapi_key	json_modec                 t   |j                         }|j                  |d|d|i       d|v rXt        |d         dkD  rG|d   d   }d|v r;d|d   v r4|d   d   }| j                  |      \  }}||d   d<   |r||d   d	<   |d   d= t	        di |}d
|j
                  xs dz   |_        |||j                  d<   |S )Nr4   complete_input_dict)r;   rQ   original_responseadditional_argschoicesr   messager2   contentrD   z
snowflake/r   r&   )r@   	post_calllenrI   r   r   _hidden_params)r'   r   rJ   rK   rL   rM   rN   r*   rO   rP   rQ   rR   response_jsonchoicer2   rC   rD   returned_responses                     r   transform_responsez"SnowflakeConfig.transform_responsey   s    %))++2LA	 	 	
 %#mI.F*G!*K"9-a0FF"~	9J'J%i0@ GGU  0<y!),6@F9%l3 9%n5):M:".2C2I2I2OR"P8=,,W5  r   headersapi_basec                 R    |t        d      |j                  ddd|z   dd       |S )a  
        Return headers to use for Snowflake completion request

        Snowflake REST API Ref: https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-llm-rest-api#api-reference
        Expected headers:
        {
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Authorization": "Bearer " + <JWT>,
            "X-Snowflake-Authorization-Token-Type": "KEYPAIR_JWT"
        }
        zMissing Snowflake JWT keyzapplication/jsonzBearer KEYPAIR_JWT)zContent-TypeAcceptAuthorizationz$X-Snowflake-Authorization-Token-Type)
ValueErrorupdate)r'   ra   r   rN   r*   rO   rQ   rb   s           r   validate_environmentz$SnowflakeConfig.validate_environment   s>    . ?899 2,!*W!48E		
 r   c                 h    |xs dt        d       dxs t        d      }|xs t        d      }||fS )Nhttps://SNOWFLAKE_ACCOUNT_ID8.snowflakecomputing.com/api/v2/cortex/inference:completeSNOWFLAKE_API_BASESNOWFLAKE_JWTr
   )r'   rb   rQ   dynamic_api_keys       r   $_get_openai_compatible_provider_infoz4SnowflakeConfig._get_openai_compatible_provider_info   sO      4N+ABCC{~423 	
 "D^O%D((r   streamc                 (    |sdt        d       d}|S )zc
        If api_base is not provided, use the default DeepSeek /chat/completions endpoint.
        rk   rl   rm   r
   )r'   rb   rQ   r   r*   rO   rr   s          r   get_complete_urlz SnowflakeConfig.get_complete_url   s)     #N3I$J#K  LD  GHr   r$   c           
          g }|D ]s  }|j                  d      dk(  s|j                  di       }dd|j                  d      |j                  ddi d      d	i}d
|v r|d
   |d   d
<   |j                  |       u |S )a  
        Transform OpenAI tool format to Snowflake tool format.

        Args:
            tools: List of tools in OpenAI format

        Returns:
            List of tools in Snowflake format

        OpenAI format:
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "...",
                "parameters": {...}
            }
        }

        Snowflake format:
        {
            "tool_spec": {
                "type": "generic",
                "name": "get_weather",
                "description": "...",
                "input_schema": {...}
            }
        }
        r5   r9   	tool_specgenericr:   
parametersobject)r5   
properties)r5   r:   input_schemadescription)r?   rB   )r'   r$   snowflake_toolstoolr9   snowflake_tools         r   _transform_toolsz SnowflakeConfig._transform_tools   s    < 13Dxx:-88J3 ) (V 4(0(%-R@)"	2 !H,AI%BN;/>  &&~6' * r   r%   c                     t        |t              r|S t        |t              r=|j                  d      dk(  r)|j                  di       j                  d      }|rd|gdS |S )a  
        Transform OpenAI tool_choice format to Snowflake format.

        Args:
            tool_choice: Tool choice in OpenAI format (str or dict)

        Returns:
            Tool choice in Snowflake format

        OpenAI format:
        {"type": "function", "function": {"name": "get_weather"}}

        Snowflake format:
        {"type": "tool", "name": ["get_weather"]}

        Note: String values ("auto", "required", "none") pass through unchanged.
        r5   r9   r:   r~   )r5   r:   )
isinstancestrdictr?   )r'   r%   function_names      r   _transform_tool_choicez&SnowflakeConfig._transform_tool_choice"  sg    ( k3'k4(v&*4 +
B ? C CF K  &!. 
 r   c                    |j                  dd       xs d}|j                  di       }|j                  dd       }|r| j                  |      |d<   |j                  dd       }	|	r| j                  |	      |d<   |||d||S )Nrr   F
extra_bodyr$   r%   )r   rN   rr   )popr   r   )
r'   r   rN   r*   rO   ra   rr   r   r$   r%   s
             r   transform_requestz!SnowflakeConfig.transform_requestE  s     '**8T:Ce$((r:
  ##GT2'+'<'<U'COG$ &))->-1-H-H-UOM*  
 	

 
 	
r   )NNr   ) __name__
__module____qualname____doc__classmethodr   r   r   r(   r   boolr1   r   r   r   r   r   rI   httpxResponser   LiteLLMLoggingObjr   r`   ri   rq   rt   r   r	   r   r   __classcell__)r   s   @r   r   r      s    $ $
 
c 
   	
  
01@ c3h01@	sHT"?@AA	B1@| "&$(1!1! nn1! &	1!
 '1! 1! '(1! 1! 1! 1! #1! D>1! 
1!t "&"&"" " '(	"
 " " #" 3-" 
"H	) 	)08	)	x}hsm+	,	)$ "&3- # 	
    
"4d4S>&: 4tDcN?S 4l! d38n!45!	sDcN"	#!F

 '(
 	

 
 
 

r   r   )r   r@   typingr   r   r   r   r   r   r	   r   litellm.secret_managers.mainr   litellm.types.llms.openair   litellm.types.utilsr   r   r   openai_like.chat.transformationr   *litellm.litellm_core_utils.litellm_loggingr   _LiteLLMLoggingObjr   r   r&   r   r   <module>r      sJ     I I I  7 6 V V >X*I
o I
r   