o
    Zh8-                     @  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 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 ddl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%m&Z& erjddl'm(Z) e*e+Z,G dd de-Z.d+ddZ/d,ddZ0d-ddZ1d.d d!Z2d/d&d'Z3d/d(d)Z4G d*d# d#eeZ5dS )0z&Wrapper around Google's PaLM Chat API.    )annotationsN)TYPE_CHECKINGAnyCallableDictListOptionalcast)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)BaseChatModel)	AIMessageBaseMessageChatMessageHumanMessageSystemMessage)ChatGeneration
ChatResult)convert_to_secret_strget_from_dict_or_envpre_init)	BaseModel	SecretStr)before_sleep_logretryretry_if_exception_typestop_after_attemptwait_exponentialc                   @  s   e Zd ZdZdS )ChatGooglePalmErrorz!Error with the `Google PaLM` API.N)__name__
__module____qualname____doc__ r#   r#   b/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/chat_models/google_palm.pyr   (   s    r   textstrstopOptional[List[str]]returnc                 C  s8   |du 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,   responsegenai.types.ChatResponser   c              	   C  s   | j stdg }| j D ]U}|d}|du rtd| t|dd|}|du r2td| |dkrC|t|t|d	d
 q|dkrT|t|t|d	d
 q|t|t||dd
 qt	|dS )z9Converts a PaLM API response into a LangChain ChatResult.z.ChatResponse must have at least one candidate.authorNz"ChatResponse must have an author: content z"ChatResponse must have a content: ai)r0   )r%   messagehuman)roler0   )generations)

candidatesr   getr,   appendr   r   r   r   r   )r-   r'   r6   	candidater/   r0   r#   r#   r$   _response_to_result;   s8   



r;   input_messagesList[BaseMessage]genai.types.MessagePromptDictc           
      C  sp  ddl m} d}g }g }tt| }|r|d\}}t|tr/|dkr(tdtt	|j
}n~t|trf|jrf|r=td|d\}}	t|	trb|	jrb||jjd|j
d|jjd|	j
dg nKtd	t|trr|jrrtd
t|tr||jjd|j
d n)t|tr||jjd|j
d nt|tr||jj|j|j
d ntd|s|jj|||dS )zNConverts a list of LangChain messages into a PaLM API MessagePrompt structure.r   Nr1   z+System message must be first input message.z1Message examples must come before other messages.r4   )r/   r0   r2   zNHuman example message must be immediately followed by an  AI example response.zKAI example message must be immediately preceded by a Human example message.z<Messages without an explicit role not supported by PaLM API.)contextexamplesmessages)google.generativeaigenerativeailist	enumeratepop
isinstancer   r   r	   r&   r0   r   Zexampler   extendtypesZMessageDictr9   r   r5   ZMessagePromptDict)
r<   genair?   r@   rA   	remainingindexZinput_message_Znext_input_messager#   r#   r$   _messages_to_prompt_dictc   sr   



5rN   Callable[[Any], Any]c                  C  sf   ddl } d}d}d}d}tdt|t|||dt| jjjt| jjjB t| jjj	B t
ttjd	S )
zKReturns a tenacity retry decorator, preconfigured to handle PaLM exceptionsr   N      <   
   T)
multiplierminmax)reraiser'   waitr   before_sleep)Zgoogle.api_core.exceptionsr   r   r   r   Zapi_core
exceptionsZResourceExhaustedZServiceUnavailableZGoogleAPIErrorr   loggerloggingWARNING)googlerT   Zmin_secondsZmax_secondsmax_retriesr#   r#   r$   _create_retry_decorator   s    
r`   llmChatGooglePalmkwargsr   c                   s&   t  }|d fdd}|di |S )	z*Use tenacity to retry the completion call.rc   r   r)   c                    s    j jdi | S Nr#   )clientZchatrc   ra   r#   r$   _chat_with_retry   s   z)chat_with_retry.<locals>._chat_with_retryNrc   r   r)   r   r#   r`   )ra   rc   retry_decoratorrh   r#   rg   r$   chat_with_retry   s   rl   c                   s.   t  }|d fdd}|di |I dH S )	z0Use tenacity to retry the async completion call.rc   r   r)   c                    s    j jdi | I d H S rd   )re   Z
chat_asyncrf   rg   r#   r$   _achat_with_retry   s   z+achat_with_retry.<locals>._achat_with_retryNri   r#   rj   )ra   rc   rk   rm   r#   rg   r$   achat_with_retry   s
   rn   c                   @  s   e Zd ZU 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< 	 ed2ddZed3ddZed4ddZed5ddZ		d6d7d(d)Z		d6d8d+d,Zed9d.d/Zed:d0d1ZdS );rb   a  `Google PaLM` Chat models API.

    To use you must have the google.generativeai Python package installed and
    either:

        1. The ``GOOGLE_API_KEY`` environment variable set with your API key, or
        2. Pass your API key using the google_api_key kwarg to the ChatGoogle
           constructor.

    Example:
        .. code-block:: python

            from langchain_community.chat_models import ChatGooglePalm
            chat = ChatGooglePalm()

    r   re   zmodels/chat-bison-001r&   
model_nameNzOptional[SecretStr]google_api_keyzOptional[float]temperaturetop_pzOptional[int]top_krQ   intnr)   Dict[str, str]c                 C  s   ddiS )Nrp   GOOGLE_API_KEYr#   selfr#   r#   r$   
lc_secrets   s   zChatGooglePalm.lc_secretsboolc                 C     dS )NTr#   rx   r#   r#   r$   is_lc_serializable      z!ChatGooglePalm.is_lc_serializable	List[str]c                 C  s   g dS )z*Get the namespace of the langchain object.)Z	langchainZchat_modelsZgoogle_palmr#   )clsr#   r#   r$   get_lc_namespace  s   zChatGooglePalm.get_lc_namespacevaluesr   c                 C  s   t t|dd}zddlm} |j| d W n ty#   tdw ||d< |d durBd|d   kr=d	ksBtd
 td
|d dur\d|d   krWd	ks\td td|d durl|d dkrltd|S )zGValidate api key, python package exists, temperature, top_p, and top_k.rp   rw   r   N)Zapi_keyzmCould not import google.generativeai python package. Please install it with `pip install google-generativeai`re   rq   rQ   z+temperature must be in the range [0.0, 1.0]rr   z%top_p must be in the range [0.0, 1.0]rs   ztop_k must be positive)	r   r   rB   rC   	configureZget_secret_valueImportErrorr   
ValueError)r   r   rp   rJ   r#   r#   r$   validate_environment  s.   
""z#ChatGooglePalm.validate_environmentrA   r=   r'   r(   run_manager"Optional[CallbackManagerForLLMRun]rc   r   c              	   K  s:   t |}t| f| j|| j| j| j| jd|}t||S N)modelpromptrq   rr   rs   Zcandidate_count)rN   rl   ro   rq   rr   rs   ru   r;   ry   rA   r'   r   rc   r   r-   r#   r#   r$   	_generate%  s   
zChatGooglePalm._generate'Optional[AsyncCallbackManagerForLLMRun]c              	     s:   t |}t| | j|| j| j| j| jdI d H }t||S r   )rN   rn   ro   rq   rr   rs   ru   r;   r   r#   r#   r$   
_agenerate;  s   

zChatGooglePalm._agenerateDict[str, Any]c                 C  s   | j | j| j| j| jdS )zGet the identifying parameters.ro   rq   rr   rs   ru   r   rx   r#   r#   r$   _identifying_paramsP  s   z"ChatGooglePalm._identifying_paramsc                 C  r|   )Nzgoogle-palm-chatr#   rx   r#   r#   r$   	_llm_type[  r~   zChatGooglePalm._llm_type)r)   rv   )r)   r{   )r)   r   )r   r   r)   r   )NN)
rA   r=   r'   r(   r   r   rc   r   r)   r   )
rA   r=   r'   r(   r   r   rc   r   r)   r   )r)   r   )r)   r&   )r   r    r!   r"   __annotations__ro   rp   rq   rr   rs   ru   propertyrz   classmethodr}   r   r   r   r   r   r   r   r#   r#   r#   r$   rb      s@   
 
)r%   r&   r'   r(   r)   r&   )r-   r.   r'   r(   r)   r   )r<   r=   r)   r>   )r)   rO   )ra   rb   rc   r   r)   r   )6r"   
__future__r   r\   typingr   r   r   r   r   r   r	   Zlangchain_core.callbacksr
   r   Z*langchain_core.language_models.chat_modelsr   Zlangchain_core.messagesr   r   r   r   r   Zlangchain_core.outputsr   r   Zlangchain_core.utilsr   r   r   Zpydanticr   r   tenacityr   r   r   r   r   rB   rC   rJ   	getLoggerr   r[   	Exceptionr   r,   r;   rN   r`   rl   rn   rb   r#   r#   r#   r$   <module>   s,    $



(
H

