U
    hJ                     @  s0  d Z ddlmZ ddl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mZ ddlZddlZddlmZmZ ddlmZ ddlmZ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)m*Z*m+Z+m,Z, dd
l-m.Z. ddl-m/Z0 ddl1m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZB eCeDZEG dd deFZGdCddddddZHdddddZIdd dd!d"ZJd#d$d%d&d'ZKd#d(d)d*d+d,ZLd$dd-d.d/ZMG d0d deZNd1d2d3d4d5ZOd6d7d3d8d9ZPd:d;d<d=d>ZQd?d@d<dAdBZRdS )Dz!deepinfra.com chat models wrapper    )annotationsN)AnyAsyncIteratorCallableDictIteratorListMappingOptionalSequenceTupleTypeUnion)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)LanguageModelInput)BaseChatModelagenerate_from_streamgenerate_from_stream)create_base_retry_decorator)	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkFunctionMessageFunctionMessageChunkHumanMessageHumanMessageChunkSystemMessageSystemMessageChunkToolMessage)ToolCall	tool_call)ChatGenerationChatGenerationChunk
ChatResult)	BaseModelFieldroot_validator)Runnable)BaseToolget_from_dict_or_envconvert_to_openai_tool)Requestsc                   @  s   e Zd ZdZdS )ChatDeepInfraExceptionz9Exception raised when the DeepInfra API returns an error.N)__name__
__module____qualname____doc__ r8   r8   M/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/chat_models/deepinfra.pyr3   D   s   r3   ChatDeepInfrazHOptional[Union[AsyncCallbackManagerForLLMRun, CallbackManagerForLLMRun]]zCallable[[Any], Any])llmrun_managerreturnc                 C  s   t tjjtg| j|dS )zLReturns a tenacity retry decorator, preconfigured to handle PaLM exceptions.)Zerror_typesmax_retriesr<   )r   requests
exceptionsConnectTimeoutr3   r>   )r;   r<   r8   r8   r9   _create_retry_decoratorJ   s
    
rB   dictr#   )r%   r=   c                 C  s:   | d  dd}t| d d }|  d}t|||dS )zw
    Convert a tool calling response from server to a ToolCall object.
    Args:
        tool_call:

    Returns:

    functionname 	argumentsid)rE   argsrH   )getjsonloadscreate_tool_call)r%   rE   rI   rH   r8   r8   r9   _parse_tool_callingX   s    	
rN   Dict[str, Any]c                 C  s&   dt | d | d d| ddS )zu
    Convert a ToolCall object to a tool calling request for server.
    Args:
        tool_call:

    Returns:

    rD   rI   rE   )rG   rE   rH   )typerD   rH   )rK   dumpsrJ   r$   r8   r8   r9   _convert_to_tool_callingg   s    
rR   Mapping[str, Any]r   )_dictr=   c                 C  s   | d }|dkrt | d dS |dkr`| ddp4d}| dg pDg }dd	 |D }t||d
S |dkrvt| d dS |dkrt| d | d dS t| d |dS d S )NroleusercontentrW   	assistantrF   
tool_callsc                 S  s   g | ]}t |qS r8   rN   .0r%   r8   r8   r9   
<listcomp>   s    z,_convert_dict_to_message.<locals>.<listcomp>rW   rZ   systemrD   rE   rW   rE   rW   rU   )r   rJ   r   r    r   r   )rT   rU   rW   Ztool_calls_contentrZ   r8   r8   r9   _convert_dict_to_messagez   s    rc   zType[BaseMessageChunk]r   )rT   default_classr=   c                 C  s   |  d}|  dpd}|dks(|tkr2t|dS |dksB|tkrddd |  d	g D }t||d
S |dkst|tkr~t|dS |dks|tkrt|| d dS |s|tkrt||dS ||dS d S )NrU   rW   rF   rV   rX   rY   c                 S  s   g | ]}t |qS r8   r[   r\   r8   r8   r9   r^      s    z3_convert_delta_to_message_chunk.<locals>.<listcomp>rZ   r_   r`   rD   rE   ra   rb   )rJ   r   r   r!   r   r   )rT   rd   rU   rW   rZ   r8   r8   r9   _convert_delta_to_message_chunk   s     



re   )messager=   c                 C  s   t | tr| j| jd}nt | tr2d| jd}nt | tr\dd | jD }d| j|d}nbt | trtd| jd}nJt | trd| j| j	d	}n.t | t
rd
| j| j	| jd}ntd|  d| jkr| jd |d< |S )N)rU   rW   rV   c                 S  s   g | ]}t |qS r8   )rR   r\   r8   r8   r9   r^      s    z,_convert_message_to_dict.<locals>.<listcomp>rY   )rU   rW   rZ   r`   rD   )rU   rW   rE   tool)rU   rW   rE   tool_call_idzGot unknown type rE   )
isinstancer   rU   rW   r   r   rZ   r    r   rE   r"   rh   
ValueErrorZadditional_kwargs)rf   Zmessage_dictrZ   r8   r8   r9   _convert_message_to_dict   s:    






rk   c                      s>  e Zd ZU dZedddZded< dZded	< edd
dZded< dZ	ded< ee
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< dZded< G dd dZeddd d!Zeddd"d#Zdad$d%d%d&d'd(Zdbd)d%d%d&d*d+Zed,d-d.d.d/d0d1Zedd,d2d.d.d/d3d4Zdcd5d6d$d7d%d8d9d:d;Zd<d8d=d>d?Zd5d6d@dAdBdCZddd5d6d$d%dDdEdFdGZded5d6d)d%dHdEdIdJZdfd5d6d)d7d%d8d9dKdLZ edddMdNZ!edddOdPZ"dd%dQdRdSdTZ#dddUdVZ$d.ddWdXZ%d%d.dYdZd[Z&d\d%d]d^ fd_d`Z'  Z(S )gr:   z)A chat model that uses the DeepInfra API.zmeta-llama/Llama-2-70b-chat-hfmodel)defaultaliasstr
model_nameNOptional[str]deepinfra_api_tokentimeoutzOptional[float]request_timeout   temperature)default_factoryrO   model_kwargstop_pzOptional[int]top_kintn   
max_tokensFbool	streamingr>   c                   @  s   e Zd ZdZdZdS )zChatDeepInfra.Configz'Configuration for this pydantic object.TN)r4   r5   r6   r7   Zallow_population_by_field_namer8   r8   r8   r9   Config   s   r   )r=   c                 C  s$   | j | j| j| j| j| jd| jS )z2Get the default parameters for calling OpenAI API.)rl   r~   streamr|   rv   rt   )rp   r~   r   r|   rv   rt   rx   selfr8   r8   r9   _default_params   s    zChatDeepInfra._default_paramsc                 C  s   | j S )z.Get the parameters used for the openai client.)r   r   r8   r8   r9   _client_params   s    zChatDeepInfra._client_paramsz"Optional[CallbackManagerForLLMRun]r   )r<   kwargsr=   c                   s.   t  |d}|ddd fdd}|f |S )z*Use tenacity to retry the completion call.r<   r   r   r=   c               
     s|   zH|  d}t  d}|j   | |d} |j|j |W S  t	k
rv } zt
d|  W 5 d }~X Y nX d S Nrt   headersurldatars   ZEX)popr2   _headerspost_url_body_handle_statusstatus_codetext	Exceptionprintr   rt   requestresponseer   r8   r9   _completion_with_retry   s    
  
zCChatDeepInfra.completion_with_retry.<locals>._completion_with_retryrB   r   r<   r   Zretry_decoratorr   r8   r   r9   completion_with_retry   s    z#ChatDeepInfra.completion_with_retryz'Optional[AsyncCallbackManagerForLLMRun]c                   s4   t  |d}|ddd fdd}|f |I dH S )z0Use tenacity to retry the async completion call.r   r   r   c                    s   z~|  d}t  d}|j   | |d4 I d H 4} |j|j |	 I d H W  5 Q I d H R  W S Q I d H R X W n. t
k
r } ztd|  W 5 d }~X Y nX d S r   )r   r2   r   apostr   r   r   statusr   rK   r   r   r   r   r8   r9   r     s    
  2
zDChatDeepInfra.acompletion_with_retry.<locals>._completion_with_retryNr   r   r8   r   r9   acompletion_with_retry  s    z$ChatDeepInfra.acompletion_with_retryT)prer   )valuesr=   c                 C  s(   t |dddd}t |dd|d|d< |S )zGValidate api key, python package exists, temperature, top_p, and top_k.Zdeepinfra_api_keyZDEEPINFRA_API_KEYrF   )rm   rr   ZDEEPINFRA_API_TOKENr.   )clsr   Zapi_keyr8   r8   r9   init_defaults&  s    
zChatDeepInfra.init_defaults)r   Zskip_on_failurec                 C  s   |d d k	r.d|d   kr$dks.n t d|d d k	r\d|d   krRdks\n t d|d d k	r||d dkr|t d|S )	Nrv   r   ru   z+temperature must be in the range [0.0, 1.0]ry   z%top_p must be in the range [0.0, 1.0]rz   ztop_k must be positive)rj   )r   r   r8   r8   r9   validate_environment8  s    &&z"ChatDeepInfra.validate_environmentzList[BaseMessage]zOptional[List[str]]zOptional[bool]r(   )messagesstopr<   r   r   r=   c                 K  sr   |d k	r|n| j }|r6| j|f||d|}t|S | ||\}}	|	|}	| jf ||d|	}
| |
 S )Nr   r<   r   r<   )r   _streamr   _create_message_dictsr   _create_chat_resultrK   )r   r   r   r<   r   r   should_streamstream_itermessage_dictsparamsr   r8   r8   r9   	_generateE  s(      zChatDeepInfra._generaterS   )r   r=   c                 C  sh   g }|d D ]2}t |d }t|t|ddd}|| q|di }|| jd}t||d}|S )	Nchoicesrf   finish_reason)r   rf   Zgeneration_infousage)token_usagerl   )generations
llm_output)rc   r&   rC   rJ   appendrp   r(   )r   r   r   resrf   genr   r   r8   r8   r9   r   [  s    z!ChatDeepInfra._create_chat_resultz+Tuple[List[Dict[str, Any]], Dict[str, Any]])r   r   r=   c                 C  s<   | j }|d k	r&d|krtd||d< dd |D }||fS )Nr   z2`stop` found in both the input and default params.c                 S  s   g | ]}t |qS r8   )rk   )r]   mr8   r8   r9   r^   q  s     z7ChatDeepInfra._create_message_dicts.<locals>.<listcomp>)r   rj   )r   r   r   r   r   r8   r8   r9   r   i  s    z#ChatDeepInfra._create_message_dictszIterator[ChatGenerationChunk])r   r   r<   r   r=   c                 k  s   |  ||\}}||ddi}| jf ||d|}t| D ]:}t|}	|	r@t|	d d}
|rt|jt|	j|
d |
V  q@d S )Nr   Tr   r   chunk)	r   r   _parse_stream
iter_lines_handle_sse_liner'   on_llm_new_tokenro   rW   )r   r   r   r<   r   r   r   r   liner   cg_chunkr8   r8   r9   r   t  s     zChatDeepInfra._streamz"AsyncIterator[ChatGenerationChunk]c              
   K s   |  ||\}}|dd||}|d}t|  d}|j|  | ||d4 I d H \}	t|	j2 zH3 d H W }
t	|
}|rft
|d d}|r|jt|j|dI d H  |V  qf6 W 5 Q I d H R X d S )NT)r   r   rt   r   r   r   r   )r   r   r2   r   r   r   r   _parse_stream_asyncrW   r   r'   r   ro   )r   r   r   r<   r   r   r   rt   r   r   r   r   r   r8   r8   r9   _astream  s(    
   zChatDeepInfra._astreamc                   s~   |d k	r|n| j }|r<| j|f||d|}t|I d H S | ||\}}	d|i|	|}	| jf d|i|	I d H }
| |
S )Nr   r   r<   )r   r   r   r   r   r   )r   r   r   r<   r   r   r   r   r   r   r   r8   r8   r9   
_agenerate  s     zChatDeepInfra._ageneratec                 C  s   | j | j| j| j| jdS )zGet the identifying parameters.)rl   rv   ry   rz   r|   )rp   rv   ry   rz   r|   r   r8   r8   r9   _identifying_params  s    z!ChatDeepInfra._identifying_paramsc                 C  s   dS )Nzdeepinfra-chatr8   r   r8   r8   r9   	_llm_type  s    zChatDeepInfra._llm_typeNone)coder   r=   c                 C  sV   |dkrt d| d| n4|dkr6td| n|dkrRtd| d| d S )Ni  zDeepInfra Server error status z: i  z'DeepInfra received an invalid payload:    z6DeepInfra returned an unexpected response with status )r3   rj   r   )r   r   r   r8   r8   r9   r     s    zChatDeepInfra._handle_statusc                 C  s   dS )Nz:https://stage.api.deepinfra.com/v1/openai/chat/completionsr8   r   r8   r8   r9   r     s    zChatDeepInfra._urlc                 C  s   d| j  ddS )Nzbearer zapplication/json)AuthorizationzContent-Type)rr   r   r8   r8   r9   r     s    
zChatDeepInfra._headersr   c                 C  s   |S Nr8   )r   r   r8   r8   r9   r     s    zChatDeepInfra._bodyzDSequence[Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]]z)Runnable[LanguageModelInput, BaseMessage])toolsr   r=   c                   s$   dd |D }t  jf d|i|S )a3  Bind tool-like objects to this chat model.

        Assumes model is compatible with OpenAI tool-calling API.

        Args:
            tools: A list of tool definitions to bind to this chat model.
                Can be  a dictionary, pydantic model, callable, or BaseTool. Pydantic
                models, callables, and BaseTools will be automatically converted to
                their schema dictionary representation.
            **kwargs: Any additional parameters to pass to the
                :class:`~langchain.runnable.Runnable` constructor.
        c                 S  s   g | ]}t |qS r8   r0   )r]   rg   r8   r8   r9   r^     s     z,ChatDeepInfra.bind_tools.<locals>.<listcomp>r   )superbind)r   r   r   Zformatted_tools	__class__r8   r9   
bind_tools  s    zChatDeepInfra.bind_tools)N)N)NNN)NN)NN)NNN))r4   r5   r6   r7   r*   rp   __annotations__rr   rt   rv   rC   rx   ry   rz   r|   r~   r   r>   r   propertyr   r   r   r   r+   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r8   r8   r   r9   r:      sd   
  
          
zIterator[bytes]zIterator[str])rbodyr=   c                 c  s$   | D ]}t |}|d k	r|V  qd S r   _parse_stream_helperr   r   _liner8   r8   r9   r     s    r   zaiohttp.StreamReaderzAsyncIterator[str]c                 C s.   | 2 z"3 d H W }t |}|d k	r|V  q6 d S r   r   r   r8   r8   r9   r     s    r   bytesrq   )r   r=   c                 C  sX   | rT|  drT|  dr*| tdd  } n| tdd  } |  dkrJd S | dS d S )Ns   data:s   data: s   [DONE]zutf-8)
startswithlenstripdecode)r   r8   r8   r9   r     s    

r   ro   zOptional[BaseMessageChunk]c                 C  sP   z4t | }t}|di gd di }t||W S  tk
rJ   Y d S X d S )Nr   r   delta)rK   rL   r   rJ   re   r   )r   objZdefault_chunk_classr   r8   r8   r9   r     s    
r   )N)Sr7   
__future__r   rK   loggingtypingr   r   r   r   r   r   r	   r
   r   r   r   r   Zaiohttpr?   Z langchain_core.callbacks.managerr   r   Zlangchain_core.language_modelsr   Z*langchain_core.language_models.chat_modelsr   r   r   Z#langchain_core.language_models.llmsr   Zlangchain_core.messagesr   r   r   r   r   r   r   r   r   r   r    r!   r"   Zlangchain_core.messages.toolr#   r%   rM   Zlangchain_core.outputsr&   r'   r(   Zlangchain_core.pydantic_v1r)   r*   r+   Zlangchain_core.runnablesr,   Zlangchain_core.toolsr-   Zlangchain_core.utilsr/   Z%langchain_core.utils.function_callingr1   Z&langchain_community.utilities.requestsr2   	getLoggerr4   loggerr   r3   rB   rN   rR   rc   re   rk   r:   r   r   r   r   r8   r8   r8   r9   <module>   sH   8<

 $  /