U
    h)                     @  s   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 ddlmZ ddl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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) e*e+Z,G dd deZ-dS )zWrapper around Perplexity APIs.    )annotationsN)	AnyDictIteratorListMappingOptionalTupleTypeUnion)CallbackManagerForLLMRun)BaseChatModelgenerate_from_stream)	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkFunctionMessageChunkHumanMessageHumanMessageChunkSystemMessageSystemMessageChunkToolMessageChunk)ChatGenerationChatGenerationChunk
ChatResult)Fieldroot_validator)get_from_dict_or_envget_pydantic_field_namesc                   @  s  e Zd ZU dZded< dZde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< 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d%d&d'Zedd#d(d)d)d%d*d+Zedd d,d-Zd.dd/d0d1Zd2d3d4d5d6d7Zd8d9d:d;d<d=ZdJd2d3d>dd?d@dAdBZdKd2d3d>ddCd@dDdEZed8d dFdGZedd dHdIZdS )LChatPerplexitya@  `Perplexity AI` Chat models API.

    To use, you should have the ``openai`` python package installed, and the
    environment variable ``PPLX_API_KEY`` set to your API key.
    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 ChatPerplexity

            chat = ChatPerplexity(
                model="llama-3.1-sonar-small-128k-online",
                temperature=0.7,
            )
    r   clientz!llama-3.1-sonar-small-128k-onlinestrmodelgffffff?floattemperature)default_factoryzDict[str, Any]model_kwargsNapi_key)aliaszOptional[str]pplx_api_keytimeoutz+Optional[Union[float, Tuple[float, float]]]request_timeout   intmax_retriesFbool	streamingzOptional[int]
max_tokensc                   @  s   e Zd ZdZdS )zChatPerplexity.ConfigTN)__name__
__module____qualname__Zallow_population_by_field_name r8   r8   N/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/chat_models/perplexity.pyConfigT   s   r:   zDict[str, str])returnc                 C  s   ddiS )Nr,   PPLX_API_KEYr8   selfr8   r8   r9   
lc_secretsW   s    zChatPerplexity.lc_secretsT)pre)valuesr;   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.r)   zFound z supplied twice.z	WARNING! z1 is not a 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)clsrA   Zall_required_field_namesextra
field_nameZinvalid_model_kwargsr8   r8   r9   build_extra[   s"    
zChatPerplexity.build_extra)r@   Zskip_on_failurer   c                 C  sv   t |dd|d< zddl}W n tk
r8   tdY nX z|j|d dd|d< W n tk
rp   td	Y nX |S )
z?Validate that api key and python package exists in environment.r,   r<   r   NzTCould not import openai python package. Please install it with `pip install openai`.https://api.perplexity.ai)r*   base_urlr#   z`openai` has no `ChatCompletion` attribute, this is likely due to an old version of the openai package. Try upgrading it with `pip install --upgrade openai`.)r    openaiImportErrorZOpenAIAttributeErrorrD   )rJ   rA   rP   r8   r8   r9   validate_environmentu   s*      
 
z#ChatPerplexity.validate_environmentc                 C  s   | j | j| j| jd| jS )z:Get the default parameters for calling PerplexityChat API.)r.   r4   streamr'   )r.   r4   r3   r'   r)   r=   r8   r8   r9   _default_params   s    zChatPerplexity._default_paramsr   )messager;   c                 C  st   t |tr|j|jd}nVt |tr2d|jd}n>t |trJd|jd}n&t |trbd|jd}ntd| |S )N)rolecontentsystemuser	assistantzGot unknown type )
isinstancer   rW   rX   r   r   r   	TypeError)r>   rV   Zmessage_dictr8   r8   r9   _convert_message_to_dict   s    



z'ChatPerplexity._convert_message_to_dictzList[BaseMessage]zOptional[List[str]]z+Tuple[List[Dict[str, Any]], Dict[str, Any]])messagesstopr;   c                   sD   t  j}|d k	r*d|kr"td||d<  fdd|D }||fS )Nr`   z2`stop` found in both the input and default params.c                   s   g | ]}  |qS r8   )r^   ).0mr=   r8   r9   
<listcomp>   s     z8ChatPerplexity._create_message_dicts.<locals>.<listcomp>)dict_invocation_paramsrD   )r>   r_   r`   paramsmessage_dictsr8   r=   r9   _create_message_dicts   s    
z$ChatPerplexity._create_message_dictszMapping[str, Any]zType[BaseMessageChunk]r   )_dictdefault_classr;   c                 C  s(  | d}| dpd}i }| drVt|d }d|krN|d d krNd|d< ||d< | drl|d |d< |dks||tkrt|dS |d	ks|tkrt||d
S |dks|tkrt|dS |dks|tkrt||d dS |dks|tk rt||d dS |s|tkrt||dS ||dS d S )NrW   rX    function_callnameZ
tool_callsrZ   rX   r[   )rX   additional_kwargsrY   function)rX   rm   Ztooltool_call_id)rX   rq   )rX   rW   )rB   rd   r   r   r   r   r   r   )r>   ri   rj   rW   rX   ro   rl   r8   r8   r9   _convert_delta_to_message_chunk   s.    




z.ChatPerplexity._convert_delta_to_message_chunkz"Optional[CallbackManagerForLLMRun]zIterator[ChatGenerationChunk])r_   r`   run_managerkwargsr;   c                 k  s   |  ||\}}||}t}|r(||d< | jjjj|d |dd}|D ]}	t|	ts\|	 }	t|	d dkrnqF|	d d }
| 	|
d |}	|

d}|d k	rt|d	nd }|	j}t|	|d
}	|r|j|	j|	d |	V  qFd S )NZstop_sequencesr%   T)r%   r_   rT   choicesr   deltafinish_reason)rw   )rV   generation_info)chunk)rh   r   r#   chatcompletionscreater\   rd   lenrr   rB   	__class__r   Zon_llm_new_tokentext)r>   r_   r`   rs   rt   rg   rf   Zdefault_chunk_classZstream_respry   choicerw   rx   r8   r8   r9   _stream   s8    
  
 
zChatPerplexity._streamr   c           
      K  s   | j r*| j|f||d|}|r*t|S | ||\}}||}| jjjj|d |d}t|j	d j
jd}	tt|	dgdS )N)r`   rs   r%   )r%   r_   r   rn   )rV   )Zgenerations)r3   r   r   rh   r#   rz   r{   r|   r   ru   rV   rX   r   r   )
r>   r_   r`   rs   rt   Zstream_iterrg   rf   responserV   r8   r8   r9   	_generate   s&     
 zChatPerplexity._generatec                 C  s   | j d| jd}|| jS )z,Get the parameters used to invoke the model.rN   )r*   Zapi_baser%   )r,   r%   rU   )r>   Z
pplx_credsr8   r8   r9   re     s
    z!ChatPerplexity._invocation_paramsc                 C  s   dS )zReturn type of chat model.Zperplexitychatr8   r=   r8   r8   r9   	_llm_type  s    zChatPerplexity._llm_type)NN)NN)r5   r6   r7   __doc____annotations__r%   r'   r   rd   r)   r,   r.   r1   r3   r4   r:   propertyr?   r   rM   rS   rU   r^   rh   rr   r   r   re   r   r8   r8   r8   r9   r"   ,   sF   
 

   &  	r"   ).r   
__future__r   loggingtypingr   r   r   r   r   r   r	   r
   r   Zlangchain_core.callbacksr   Z*langchain_core.language_models.chat_modelsr   r   Zlangchain_core.messagesr   r   r   r   r   r   r   r   r   r   r   r   Zlangchain_core.outputsr   r   r   Zlangchain_core.pydantic_v1r   r   Zlangchain_core.utilsr    r!   	getLoggerr5   rE   r"   r8   r8   r8   r9   <module>   s   ,8
