U
    h                      @   s  U d dl Z d dlmZmZ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mZ d dlmZmZ d dlmZmZmZ d dlmZmZmZmZ d d	lmZ d
ddgZee e d< G dd de!Z"ee#dddZ$eeee  edddZ%G dd de	Z&dS )    N)AnyDictListOptional)CallbackManagerForLLMRun)BaseChatModel)	AIMessageBaseMessageChatMessageHumanMessageSystemMessage)ChatGeneration
ChatResult)Field	SecretStrroot_validator)convert_to_secret_strget_from_dict_or_envget_pydantic_field_namespre_init)build_extra_kwargssystemuser	assistantSUPPORTED_ROLESc                   @   s   e Zd ZdZdS )ChatSnowflakeCortexErrorzError with Snowpark client.N)__name__
__module____qualname____doc__ r    r    M/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/chat_models/snowflake.pyr      s   r   )messagereturnc                 C   sx   d| j i}t| tr*| jtkr*| j|d< nJt| tr>d|d< n6t| trRd|d< n"t| trfd|d< ntd|  |S )zConvert a LangChain message to a dictionary.

    Args:
        message: The LangChain message.

    Returns:
        The dictionary.
    contentroler   r   r   zGot unknown type )	r$   
isinstancer
   r%   r   r   r   r   	TypeError)r"   Zmessage_dictr    r    r!   _convert_message_to_dict"   s    
 





r(   )textstopr#   c                 C   s8   |dkr| S |D ]"}|  |}|dkr| d| } q| S )z0Truncates text at the earliest stop token found.N)find)r)   r*   Z
stop_tokenZstop_token_idxr    r    r!   _truncate_at_stop_tokens=   s    
r-   c                   @   s  e Zd ZU dZdZeed< dZeed< dZ	eed< dZ
eed	< dZee ed
< dZee ed< edddZee ed< edddZee ed< edddZee ed< edddZee ed< edddZee ed< edddZee ed< edddZee ed< eddeeef eeef dddZeeedd d!Zdd"d#d$Zeed"d%d&Z d*e!e" ee!e  ee# ee$d'd(d)Z%dS )+ChatSnowflakeCortexa  Snowflake Cortex based Chat model

    To use you must have the ``snowflake-snowpark-python`` Python package installed and
    either:

        1. environment variables set with your snowflake credentials or
        2. directly passed in as kwargs to the ChatSnowflakeCortex constructor.

    Example:
        .. code-block:: python

            from langchain_community.chat_models import ChatSnowflakeCortex
            chat = ChatSnowflakeCortex()
    N_sp_sessionzsnowflake-arcticmodelZcompletecortex_functiongffffff?temperature
max_tokenstop_pusername)defaultaliassnowflake_usernamepasswordsnowflake_passwordaccountsnowflake_accountdatabasesnowflake_databaseschemasnowflake_schema	warehousesnowflake_warehouser%   snowflake_roleT)pre)valuesr#   c                 C   s(   t | }|di }t||||d< |S )z>Build extra kwargs from additional params that were passed in.Zmodel_kwargs)r   getr   )clsrE   Zall_required_field_namesextrar    r    r!   build_extra   s      zChatSnowflakeCortex.build_extrac              
   C   s&  zddl m} W n tk
r,   tdY nX t|dd|d< tt|dd|d< t|dd	|d< t|d
d|d
< t|dd|d< t|dd|d< t|dd|d< |d |d |d  |d
 |d |d |d d}z|j| |d< W n2 t	k
r  } zt
d| W 5 d }~X Y nX |S )Nr   )Sessionzm`snowflake-snowpark-python` package not found, please install it with `pip install snowflake-snowpark-python`r8   ZSNOWFLAKE_USERNAMEr:   ZSNOWFLAKE_PASSWORDr<   ZSNOWFLAKE_ACCOUNTr>   ZSNOWFLAKE_DATABASEr@   ZSNOWFLAKE_SCHEMArB   ZSNOWFLAKE_WAREHOUSErC   ZSNOWFLAKE_ROLE)r;   r   r9   r=   r?   rA   r%   r/   zFailed to create session: )Zsnowflake.snowparkrJ   ImportErrorr   r   Zget_secret_valueZbuilderZconfigscreate	Exceptionr   )rG   rE   rJ   Zconnection_paramser    r    r!   validate_environment   sh    
  
          

 z(ChatSnowflakeCortex.validate_environment)r#   c                 C   s   t | dd d k	r| j  d S )Nr/   )getattrr/   closeselfr    r    r!   __del__   s    zChatSnowflakeCortex.__del__c                 C   s   d| j  S )z7Get the type of language model used by this chat model.zsnowflake-cortex-)r0   rR   r    r    r!   	_llm_type   s    zChatSnowflakeCortex._llm_type)messagesr*   run_managerkwargsr#   c              
   K   s
  dd |D }t |}d| ji}| jd k	r4| j|d< | jd k	rH| j|d< t |}d| j d| j d| d	| d
	}	z| j|	 }
W n0 t	k
r } zt
d| W 5 d }~X Y nX t|
d d }|d d d }t||}t||d d}t|d}t|gdS )Nc                 S   s   g | ]}t |qS r    )r(   ).0mr    r    r!   
<listcomp>   s     z1ChatSnowflakeCortex._generate.<locals>.<listcomp>r2   r4   r3   z%
            select snowflake.cortex.z(
                'z'
                ,,z) as llm_response;z=Error while making request to Snowflake Cortex via Snowpark: r   ZLLM_RESPONSEchoicesrV   usage)r$   Zresponse_metadata)r"   )Zgenerations)strr2   r4   r3   r1   r0   r/   ZsqlZcollectrM   r   jsonloadsr-   r   r   r   )rS   rV   r*   rW   rX   Zmessage_dictsZmessage_stroptionsoptions_strZsql_stmtZl_rowsrN   responseZai_message_contentr$   r"   Z
generationr    r    r!   	_generate   s@    






zChatSnowflakeCortex._generate)NN)&r   r   r   r   r/   r   __annotations__r0   r_   r1   r2   floatr3   r   intr4   r   r8   r:   r   r<   r>   r@   rB   rC   r   r   rI   r   rO   rT   propertyrU   r   r	   r   r   re   r    r    r    r!   r.   L   s<   
"	0  
r.   )'r`   typingr   r   r   r   Z langchain_core.callbacks.managerr   Zlangchain_core.language_modelsr   Zlangchain_core.messagesr   r	   r
   r   r   Zlangchain_core.outputsr   r   Zlangchain_core.pydantic_v1r   r   r   Zlangchain_core.utilsr   r   r   r   Zlangchain_core.utils.utilsr   r   r_   rf   rM   r   dictr(   r-   r.   r    r    r    r!   <module>   s(    
