U
    hC                     @  sn  d Z ddlmZ 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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mZmZmZmZm Z m!Z!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-m.Z. ddl/m0Z0m1Z1m2Z2m3Z3m4Z4 e5e6Z7G dd deZ8dddddZ9ddddddZ:ddddddZ;dddddZ<dd d!d"d#Z=dS )$zChatYuan2 wrapper.    )annotationsN)AnyAsyncIteratorCallableDictIteratorListMappingOptionalTupleTypeUnion)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)BaseChatModelagenerate_from_streamgenerate_from_stream)	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkFunctionMessageHumanMessageHumanMessageChunkSystemMessageSystemMessageChunk)ChatGenerationChatGenerationChunk
ChatResult)	BaseModelFieldroot_validator)get_from_dict_or_envget_pydantic_field_namespre_init)before_sleep_logretryretry_if_exception_typestop_after_attemptwait_exponentialc                   @  s2  e Zd ZU dZded< edddZded< edd	d
Zded< eedZ	ded< eddd
Z
ded< eddd
Zded< eddd
Zded< dZded< dZded< dZd ed!< d"Zd#ed$< d%Zd&ed'< ed(gd)d
Zd*ed+< d,Zd ed-< d.Zd&ed/< G d0d1 d1Zed2d3d4d5Zedd3d6d7Zedd8ddd9d:d;Zed<d<d9d=d>Zedd3d?d@ZdddAdBdCZdDdEdFdGdHZdedId*dJddKdLdMdNZ dfdId*dJddOdLdPdQZ!dId*dRdSdTdUZ"dVdOdWdXdYZ#dgdId*dZdd[dLd\d]Z$dhdId*dZddOdLd^d_Z%ed`d3dadbZ&edd3dcddZ'dS )i	ChatYuan2a;  `Yuan2.0` Chat models API.

    To use, you should have the ``openai-python`` package installed, if package
    not installed, using ```pip install openai``` to install it. The
    environment variable ``YUAN2_API_KEY`` set to your API key, if not set,
    everyone can access apis.

    Any parameters that are valid to be passed to the openai.create call can be passed
    in, even if not explicitly saved on this class.

    Example:
        .. code-block:: python

            from langchain_community.chat_models import ChatYuan2

            chat = ChatYuan2()
    r   clientNT)defaultexcludeasync_clientZyuan2model)r.   aliasstr
model_name)default_factoryzDict[str, Any]model_kwargsZEMPTYapi_keyzOptional[str]yuan2_api_keyzhttp://127.0.0.1:8000/v1base_urlyuan2_api_basetimeoutz+Optional[Union[float, Tuple[float, float]]]request_timeout   intmax_retriesFbool	streamingzOptional[int]
max_tokensg      ?floattemperatureg?zOptional[float]top_pz<eod>Zstop_sequenceszOptional[List[str]]stop@   repeat_last_ngzG?repeat_penaltyc                   @  s   e Zd ZdZdS )zChatYuan2.ConfigTN)__name__
__module____qualname__Zallow_population_by_field_name rM   rM   I/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/chat_models/yuan2.pyConfig}   s   rO   zDict[str, str])returnc                 C  s   ddiS )Nr8   YUAN2_API_KEYrM   selfrM   rM   rN   
lc_secrets   s    zChatYuan2.lc_secretsc                 C  s(   i }| j r| j |d< | jr$| j|d< |S )Nr:   r8   )r:   r8   )rS   
attributesrM   rM   rN   lc_attributes   s    

zChatYuan2.lc_attributes)pre)valuesrP   c              
   C  s   t | }|di }t|D ]P}||kr8td| d||krtd| d| d| d ||||< q|| }|rtd| d	||d< |S )
z>Build extra kwargs from additional params that were passed in.r6   zFound z supplied twice.z	WARNING! z/ is not default parameter.
                    zJ was transferred to model_kwargs.
                    Please confirm that z is what you intended.zParameters za should be specified explicitly. Instead they were passed in as part of `model_kwargs` parameter.)	r%   getlist
ValueErrorloggerwarningpopintersectionkeys)clsrX   Zall_required_field_namesextra
field_nameZinvalid_model_kwargsrM   rM   rN   build_extra   s"    
zChatYuan2.build_extrar   c                 C  s   t |dd|d< zddl}W n tk
r8   tdY nX |d |d |d |d d	}|d
sv|jf |jj|d
< |ds|jf |jj|d< |S )z?Validate that api key and python package exists in environment.r8   rQ   r   NzTCould not import openai python package. Please install it with `pip install openai`.r:   r<   r?   )r7   r9   r;   r?   r-   r0   )r$   openaiImportErrorrY   ZOpenAIZchatZcompletionsZAsyncOpenAI)ra   rX   re   Zclient_paramsrM   rM   rN   validate_environment   s.      


zChatYuan2.validate_environmentc                 C  sH   | j | j| j| jd| j}| jdk	r0| j|d< | jdk	rD| j|d< |S )z1Get the default parameters for calling yuan2 API.)r1   streamrD   rE   NrB   r<   )r4   rA   rD   rE   r6   rB   r<   )rS   paramsrM   rM   rN   _default_params   s    



zChatYuan2._default_paramskwargsrP   c                   s*   t  }|ddd fdd}|f |S )z*Use tenacity to retry the completion call.r   rk   c                    s    j jf | S N)r-   createrl   rR   rM   rN   _completion_with_retry   s    z?ChatYuan2.completion_with_retry.<locals>._completion_with_retry_create_retry_decorator)rS   rl   retry_decoratorrp   rM   rR   rN   completion_with_retry   s    zChatYuan2.completion_with_retryzList[Optional[dict]]dict)llm_outputsrP   c                 C  sz   i }t dt| d|  |D ]J}|d kr0q"|d }| D ]*\}}||krb||  |7  < q@|||< q@q"|| jdS )Nztype(llm_outputs): z; llm_outputs: token_usagerw   r4   )r\   debugtypeitemsr4   )rS   rv   Zoverall_token_usageoutputrw   kvrM   rM   rN   _combine_llm_outputs   s    zChatYuan2._combine_llm_outputszList[BaseMessage]z"Optional[CallbackManagerForLLMRun]zIterator[ChatGenerationChunk])messagesrF   run_managerrl   rP   c                 k  s   |  ||\}}||ddi}t}| jf d|i|D ]}t|tsL| }t|d dkr^q6|d d }	t|	d |}|	d}
|
d k	rt|
dnd }|j	}t
||d	}|r|j|j|d
 |V  q6d S Nrh   Tr   choicesr   deltafinish_reasonr   messagegeneration_info)chunk)_create_message_dictsr   rt   
isinstanceru   
model_dumplen_convert_delta_to_message_chunkrY   	__class__r   on_llm_new_tokencontentrS   r   rF   r   rl   message_dictsri   Zdefault_chunk_classr   choicer   r   Zcg_chunkrM   rM   rN   _stream   s0    
 
zChatYuan2._streamr    c           	      K  s\   | j r&| jf |||d|}t|S | ||\}}||}| jf d|i|}| |S N)r   rF   r   r   )rA   r   r   r   rt   _create_chat_result	rS   r   rF   r   rl   Zstream_iterr   ri   responserM   rM   rN   	_generate  s      zChatYuan2._generatez+Tuple[List[Dict[str, Any]], Dict[str, Any]])r   rF   rP   c                 C  s@   t | j}|d k	r*d|kr"td||d< dd |D }||fS )NrF   z2`stop` found in both the input and default params.c                 S  s   g | ]}t |qS rM   )_convert_message_to_dict).0mrM   rM   rN   
<listcomp>0  s     z3ChatYuan2._create_message_dicts.<locals>.<listcomp>)ru   _invocation_paramsr[   )rS   r   rF   ri   r   rM   rM   rN   r   (  s    
zChatYuan2._create_message_dictszUnion[dict, BaseModel])r   rP   c                 C  s   g }t dt| d|  t|ts0| }|d D ]H}t|d }t|d d}d|krj|d |d< t||d}|| q8|d	i | j	d
}t
||dS )Nztype(response): z; response: r   r   r   r   Zlogprobsr   usagerx   )generations
llm_output)r\   ry   rz   r   ru   _convert_dict_to_messager   appendrY   r4   r    )rS   r   r   resr   r   genr   rM   rM   rN   r   3  s$    

zChatYuan2._create_chat_resultz'Optional[AsyncCallbackManagerForLLMRun]z"AsyncIterator[ChatGenerationChunk]c                 K s   |  ||\}}||ddi}t}t| fd|i|I d H 2 z3 d H W }t|tsZ| }t|d dkrlq<|d d }	t|	d |}|	d}
|
d k	rt|
dnd }|j	}t
||d	}|r|j|j|d
I d H  |V  q<6 d S r   )r   r   acompletion_with_retryr   ru   r   r   r   rY   r   r   r   r   r   rM   rM   rN   _astreamH  s<    
 
zChatYuan2._astreamc           	        sh   | j r,| jf |||d|}t|I d H S | ||\}}||}t| fd|i|I d H }| |S r   )rA   r   r   r   r   r   r   rM   rM   rN   
_ageneratek  s      zChatYuan2._agenerateMapping[str, Any]c                 C  s   d| j i}|| jS )z,Get the parameters used to invoke the model.r1   )r4   rj   )rS   Zyuan2_credsrM   rM   rN   r   }  s     zChatYuan2._invocation_paramsc                 C  s   dS )zReturn type of chat model.z
chat-yuan2rM   rR   rM   rM   rN   	_llm_type  s    zChatYuan2._llm_type)NN)NN)NN)NN)(rJ   rK   rL   __doc____annotations__r"   r0   r4   ru   r6   r8   r:   r<   r?   rA   rB   rD   rE   rF   rH   rI   rO   propertyrT   rV   r#   rd   r&   rg   rj   rt   r   r   r   r   r   r   r   r   r   rM   rM   rM   rN   r,   <   sj   
  
  $    &  r,   zCallable[[Any], Any])llmrP   c                 C  sh   dd l }d}d}tdt| jtd||dt|jt|jB t|jB t|j	B t|j
B tttjdS )Nr      <   T)Z
multiplierminmax)reraiserF   waitr(   Zbefore_sleep)re   r(   r*   r?   r+   r)   ZAPITimeoutErrorZAPIErrorZAPIConnectionErrorZRateLimitErrorZInternalServerErrorr'   r\   loggingWARNING)r   re   Zmin_secondsZmax_secondsrM   rM   rN   rr     s$    
rr   r   )r   rl   rP   c                   s0   t  }|ddd fdd}|f |I dH S )z0Use tenacity to retry the async completion call.r   rk   c                    s    j jf | I d H S rm   )r0   rn   ro   r   rM   rN   rp     s    z6acompletion_with_retry.<locals>._completion_with_retryNrq   )r   rl   rs   rp   rM   r   rN   r     s    r   r   zType[BaseMessageChunk]r   )_dictdefault_classrP   c                 C  s   |  d}|  dpd}|dks(|tkr2t|dS |dksB|tkrLt|dS |dks\|tkrft|dS |sr|tkr~t||dS ||dS d S )	Nroler    userr   	assistantsystemr   r   )rY   r   r   r   r   )r   r   r   r   rM   rM   rN   r     s    



r   r   )r   rP   c                 C  sp   |  d}|dkr$t|  dddS |dkr>t|  dddS |dkrXt|  dddS t|  dd|dS d S )	Nr   r   r   r   r   r   r   r   )rY   r   r   r   r   )r   r   rM   rM   rN   r     s    
r   ru   )r   rP   c                 C  s   t | tr| j| jd}nrt | tr2d| jd}nZt | trJd| jd}nBt | trbd| jd}n*t | tr~d| j| jd}nt	d|  d| j
kr| j
d |d< |S )	zConvert a LangChain message to a dictionary.

    Args:
        message: The LangChain message.

    Returns:
        The dictionary.
    )r   r   r   r   r   function)r   namer   zGot unknown type r   )r   r   r   r   r   r   r   r   r   r[   Zadditional_kwargs)r   Zmessage_dictrM   rM   rN   r     s"    






r   )>r   
__future__r   r   typingr   r   r   r   r   r   r	   r
   r   r   r   Zlangchain_core.callbacksr   r   Z*langchain_core.language_models.chat_modelsr   r   r   Zlangchain_core.messagesr   r   r   r   r   r   r   r   r   r   r   Zlangchain_core.outputsr   r   r    Zlangchain_core.pydantic_v1r!   r"   r#   Zlangchain_core.utilsr$   r%   r&   Ztenacityr'   r(   r)   r*   r+   	getLoggerrJ   r\   r,   rr   r   r   r   r   rM   rM   rM   rN   <module>   s&   44
  Q