a
    bgM                     @   s  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mZ d dlZd dlmZ d dlmZ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m Z 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,m-Z-m.Z.m/Z/m0Z0 d dl1m2Z2 dZ3e 4e5Z6eee edddZ7eee8ef dddZ9eedddZ:eedddZ;ee ee dddZ<ej=ddddZ>ej=dddd Z?G d!d" d"eZ@d&e@e	eeef  eegef d#d$d%ZAdS )'    N)AnyAsyncContextManagerAsyncIteratorCallableDictIteratorListOptionalTupleTypeUnioncast)SSEError)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)BaseChatModelLangSmithParams)create_base_retry_decorator)
	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkHumanMessageHumanMessageChunkSystemMessageSystemMessageChunk)ChatGenerationChatGenerationChunk
ChatResult)convert_to_secret_strget_from_env)AliasChoices
ConfigDictField	SecretStrmodel_validator)Selfz%https://clovastudio.stream.ntruss.com)ssedefault_classreturnc                 C   s   |   }| jdkr&t|}td|dS |d}|d}|dpFd}|dksX|tkrbt|dS |d	ksr|tkr|t|dS |d
ks|tkrt|dS |s|tkrt||dS ||dS d S )Nresult )contentresponse_metadatamessageroler.   user)r.   	assistantsystem)r.   r1   )jsonevent_sse_data_to_response_metadatar   getr   r   r   )r)   r*   sse_datar/   r0   r1   r.    r:   s/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/chat_models/naver.py_convert_chunk_to_message_chunk5   s     





r<   )r9   r+   c                 C   sl   i }d| v r| d |d< d| v r,| d |d< d| v r@| d |d< d| v rT| d |d< d| v rh| d |d	< |S )
N
stopReasonstop_reasoninputLengthinput_lengthoutputLengthoutput_lengthseedaiFilter	ai_filterr:   )r9   r/   r:   r:   r;   r7   L   s    r7   )r0   r+   c                 C   s~   t | trt| j| jdS t | tr2td| jdS t | trJtd| jdS t | trbtd| jdS t	d t
d|  d S )N)r1   r.   r2   r4   r3   zmFunctionMessage, ToolMessage not yet supported (https://api.ncloud-docs.com/docs/clovastudio-chatcompletions)zGot unknown type )
isinstancer   dictr1   r.   r   r   r   loggerwarning
ValueErrorr0   r:   r:   r;   &_convert_message_to_naver_chat_message[   s    



rL   )_messager+   c                 C   s   | d }|dv sJ d| t t| d }i }|dkrDt||dS |dkrXt||dS |dkrlt||dS td	| td
| d S )Nr1   )r3   r4   r2   z7Expected role to be 'assistant', 'system', 'user', got r.   r2   )r.   additional_kwargsr4   r3   zGot unknown role %szGot unknown role )r   strr   r   r   rH   rI   rJ   )rM   r1   r.   rN   r:   r:   r;   &_convert_naver_chat_message_to_messagen   s.    
rP   )event_source_mgrr+   c              	   C  s   | 4 I dH }t |jI dH  | 2 zb3 dH W }| }|jdkrl|di dkrl W d  I dH  dS |jdkrt|jd|V  q&6 W d  I dH  q1 I dH s0    Y  dS )z$Iterate over the server-sent events.Nsignaldata[DONE]errorrK   )_araise_on_errorresponseZ	aiter_sser5   r6   r8   r   rS   )rQ   event_sourcer)   
event_datar:   r:   r;   
_aiter_sse   s    
rZ   rW   r+   c                 C   sH   t j| jrD|  d}t jd| j d| j d| | j| ddS )+Raise an error if the response is an error.utf-8Error response  while fetching : requestrW   N)	httpxcodesis_errorstatus_codereaddecodeHTTPStatusErrorurlrb   rW   error_messager:   r:   r;   _raise_on_error   s    
rm   c                    sN   t j| jrJ|  I dH d}t jd| j d| j d| | j| ddS )r\   Nr]   r^   r_   r`   ra   )	rc   rd   re   rf   Zareadrh   ri   rj   rb   rk   r:   r:   r;   rV      s    
rV   c                       s  e Zd ZU dZeddZeej e	d< eddZ
eej e	d< ededdd	d
Zee	d< edddZee e	d< edddZ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	d< eddddZee e	d< eddddZee e	d < eddd!dZee e	d"< edd#d$dZee e	d%< edd&d'dZee e	d(< edd)dZeee  e	d*< eddZee e	d+< edd,ddZ ee e	d-< edd.d/Z!ee	d0< ed1d2d3Z"ee	d4< e#d5d6d7Z$e%e&ee'f d8d9d:Z(e%e&ee'f d8d;d<Z)e%e&eef d8d=d>Z*e%ed8d?d@Z+dgee,e  e'e-dA fdBdCZ.e%e&ee'f d8dDdEZ/e%ed8dFdGZ0e1dHdIe2d8dJdKZ3ed8dLdMZ4dd8dNdOZ5e&ee'f d8dPdQZ6e,e7 ee,e  e8e,e& e&ee'f f dRdSdTZ9e'e'dUdVdWZ:dhee; e'e'dXdYdZZ<e&e=d[d\d]Z>die,e7 ee,e  ee? e'e=d^d_d`Z@dje,e7 ee,e  ee? e'eAeB d^dadbZCdke,e7 ee,e  ee; e'e=d^dcddZDdle,e7 ee,e  ee; e'eEeB d^dedfZF  ZGS )m
ChatClovaXa  `NCP ClovaStudio` Chat Completion API.

    following environment variables set or passed in constructor in lower case:
    - ``NCP_CLOVASTUDIO_API_KEY``
    - ``NCP_APIGW_API_KEY``

    Example:
        .. code-block:: python

            from langchain_core.messages import HumanMessage

            from langchain_community import ChatClovaX

            model = ChatClovaX()
            model.invoke([HumanMessage(content="Come up with 10 names for a song about parrots.")])
    N)defaultclientasync_clientzHCX-003
model_namemodelzNCP ClovaStudio chat model name)ro   Zvalidation_aliasdescriptionz*NCP Clova Studio chat model tuning task ID)ro   rt   task_idFz=false: use testapp, true: use service app on NCP Clova Studioservice_appZapi_key)ro   aliasncp_clovastudio_api_keyapigw_api_keyncp_apigw_api_keyr-   base_urlg        g      ?g      ?)gtlero   temperaturer      )ger}   ro   top_kg?top_p
   g      @repeat_penaltyi   d   
max_tokensstopstop_beforeinclude_ai_filtersl    rC   Z   )r|   ro   timeout      )r   ro   max_retriesTr:   )Zpopulate_by_nameZprotected_namespacesr+   c              	   C   s<   | j | j| j| j| j| j| j| jd}dd | D }|S )z/Get the default parameters for calling the API.)r~   ZtopKZtopPZrepeatPenaltyZ	maxTokens
stopBeforeZincludeAiFiltersrC   c                 S   s   i | ]\}}|d ur||qS )Nr:   ).0kvr:   r:   r;   
<dictcomp>       z.ChatClovaX._default_params.<locals>.<dictcomp>)	r~   r   r   r   r   r   r   rC   items)selfdefaultsfilteredr:   r:   r;   _default_params   s    
zChatClovaX._default_paramsc                 C   s   | j | jd< | jS )zGet the identifying parameters.rr   )rr   r   r   r:   r:   r;   _identifying_params   s    zChatClovaX._identifying_paramsc                 C   s   |   sddiS dddS d S )Nrx   NCP_CLOVASTUDIO_API_KEYNCP_APIGW_API_KEY)rx   rz   )_is_new_api_keyr   r:   r:   r;   
lc_secrets  s    zChatClovaX.lc_secretsc                 C   s   dS )zReturn type of chat model.z
chat-naverr:   r   r:   r:   r;   	_llm_type  s    zChatClovaX._llm_type)r   kwargsr+   c                    s"   t  jf d|i|}d|d< |S )z,Get the parameters used to invoke the model.r   ZnaverZls_provider)super_get_ls_params)r   r   r   params	__class__r:   r;   r     s    zChatClovaX._get_ls_paramsc                 C   s   | j S )z'Get the parameters used for the client.)r   r   r:   r:   r;   _client_params  s    zChatClovaX._client_paramsc                 C   sJ   | j r
dnd}| jr.| j d| d| j dS | j d| d| j S dS )zGET chat completion api urlZ
serviceappZtestapp/z
/v1/tasks/z/chat-completionsz/v1/chat-completions/N)rv   ru   r{   rr   )r   Zapp_typer:   r:   r;   _api_url$  s
    zChatClovaX._api_urlafter)modec                 C   s   | j s| jstd| js*ttdd| _|  s:|   | jsNtddt	| _| j
sntj| j|  | jd| _
| jstj| j|  | jd| _| S )Nz6either model_name or task_id must be assigned a value.rx   r   r{   ZNCP_CLOVASTUDIO_API_BASE_URL)r{   headersr   )rr   ru   rJ   rx   r!   r"   r   _init_fields_on_old_api_keyr{   _DEFAULT_BASE_URLrp   rc   Clientdefault_headersr   rq   AsyncClientr   r:   r:   r;   validate_model_after0  s2    zChatClovaX.validate_model_afterc                 C   s   | j r| j  dS dS d S )Nznv-F)rx   get_secret_value
startswithr   r:   r:   r;   r   R  s    zChatClovaX._is_new_api_keyc                 C   s   | j sttddd| _ d S )Nrz   r   r-   )rz   r!   r"   r   r:   r:   r;   r   X  s    
z&ChatClovaX._init_fields_on_old_api_keyc                 C   sf   ddd}| j r| j  nd }|  r6d| |d< n,|rB||d< | jrR| j nd }|rb||d< |S )Nzapplication/json)zContent-TypeAcceptzBearer AuthorizationzX-NCP-CLOVASTUDIO-API-KEYzX-NCP-APIGW-API-KEY)rx   r   r   rz   )r   r   Zclovastudio_api_keyry   r:   r:   r;   r   ^  s$    zChatClovaX.default_headers)messagesr   r+   c                 C   s4   | j }|d urd|v r||d< dd |D }||fS )Nr   c                 S   s   g | ]}t |qS r:   )rL   )r   mr:   r:   r;   
<listcomp>  r   z4ChatClovaX._create_message_dicts.<locals>.<listcomp>)r   )r   r   r   r   message_dictsr:   r:   r;   _create_message_dicts|  s
    z ChatClovaX._create_message_dictsr   r+   c                    s   ddl m}m dvr dd< d }ttjj |r\t| d fdd}| S  jj	d}t
| | S d S )	Nr   )ServerSentEventconnect_ssestreamFr   c                  3   s    dj dx} t| j |  D ]T}| }|jdkr^|di dkr^ W d    d S |jdkrtt|jd|V  q&W d    n1 s0    Y  d S )NPOSTr5   rR   rS   rT   rU   rK   )	r   rm   rW   iter_sser5   r6   r8   r   rS   )rX   r)   rY   rp   r   r   r   r:   r;   r     s    


z3ChatClovaX._completion_with_retry.<locals>.iter_sserj   r5   )	httpx_sser   r   r   rc   r   rp   r   postr   rm   r5   )r   r   r   r   r   rW   r:   r   r;   _completion_with_retry  s    z!ChatClovaX._completion_with_retry)run_managerr   r+   c                    sF   ddl m  t|d}|ttd fdd}|f i |I d H S )Nr   )aconnect_sse)r   r   c                     st   d| vrd| d< | d }t tjj}|rD |dj| d}t|S |jj| dI d H }t|I d H  | S d S )Nr   Fr   r   r   )	r   rc   r   rq   r   rZ   r   rV   r5   )r   r   rq   rX   rW   r   r   r:   r;   r     s    
zBChatClovaX._acompletion_with_retry.<locals>._completion_with_retry)r   r   _create_retry_decoratorr   )r   r   r   Zretry_decoratorr   r:   r   r;   _acompletion_with_retry  s
    z"ChatClovaX._acompletion_with_retryr[   c                 C   s   g }| di }| di }t|}t|trX| d| d| d| d d|_t|d}|| | d| d| d| d| d	d
}t||dS )Nr,   r0   r?   rA   )Zinput_tokensZoutput_tokensZtotal_tokensrK   r=   rC   rD   )r>   r@   rB   rC   rE   )generations
llm_output)r8   rP   rF   r   Zusage_metadatar   appendr    )r   rW   r   r,   msgr0   genr   r:   r:   r;   _create_chat_result  s(    

zChatClovaX._create_chat_result)r   r   r   r   r+   c                 K   s:   |  ||\}}i ||}| jf d|i|}| |S )Nr   )r   r   r   r   r   r   r   r   r   r   rW   r:   r:   r;   	_generate  s    zChatClovaX._generatec                 k   s   |  ||\}}i ||ddi}t}| jf ||d|D ]>}t||}	|	j}t|	d}
|rv|jtt|	j	|
d |
V  q>d S Nr   Tr   r   rK   )tokenchunk)
r   r   r   r<   r   r   on_llm_new_tokenr   rO   r.   )r   r   r   r   r   r   r   default_chunk_classr)   	new_chunk	gen_chunkr:   r:   r;   _stream  s     


zChatClovaX._streamc                    sB   |  ||\}}i ||}| jf ||d|I d H }| |S )Nr   )r   r   r   r   r:   r:   r;   
_agenerate  s    zChatClovaX._ageneratec                 K  s   |  ||\}}i ||ddi}t}| jf ||d|I d H 2 zL3 d H W }t||}	|	j}t|	d}
|r|jtt|	j	|
dI d H  |
V  qD6 d S r   )
r   r   r   r<   r   r   r   r   rO   r.   )r   r   r   r   r   r   r   r   r   r   r   r:   r:   r;   _astream  s     

zChatClovaX._astream)N)N)NN)NN)NN)NN)H__name__
__module____qualname____doc__r%   rp   r	   rc   r   __annotations__rq   r   r#   rr   rO   ru   rv   boolrx   r&   rz   r{   r~   floatr   intr   r   r   r   listr   rC   r   r   r$   Zmodel_configpropertyr   r   r   r   r   r   r   r   r   r   r   r'   r(   r   r   r   r   r   r
   r   r   r   r   r    r   r   r   r   r   r   r   r   r   __classcell__r:   r:   r   r;   rn      s   
 !
%   
  
  
  
rn   )llmr   r+   c                 C   s   t jt jg}t|| j|dS )zFReturns a tenacity retry decorator, preconfigured to handle exceptions)Zerror_typesr   r   )rc   RequestErrorStreamErrorr   r   )r   r   errorsr:   r:   r;   r   1  s    r   )N)Bloggingtypingr   r   r   r   r   r   r   r	   r
   r   r   r   rc   r   r   Zlangchain_core.callbacksr   r   Z*langchain_core.language_models.chat_modelsr   r   Z#langchain_core.language_models.llmsr   Zlangchain_core.messagesr   r   r   r   r   r   r   r   r   r   Zlangchain_core.outputsr   r   r    Zlangchain_core.utilsr!   r"   Zpydanticr#   r$   r%   r&   r'   Ztyping_extensionsr(   r   	getLoggerr   rH   r<   rO   r7   rL   rP   rZ   Responserm   rV   rn   r   r:   r:   r:   r;   <module>   sP   80
!    
