o
    Zh%"                     @  s   d Z ddlmZ ddlZddl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 ddlZddlmZ ddlmZ ddlmZmZ ddlmZmZmZ dd	lmZ dd
lm Z m!Z! ddl"m#Z# erjddl$Z$e%e&Z'dZ(dZ)G dd de Z*dS )z>Anyscale Endpoints chat wrapper. Relies heavily on ChatOpenAI.    )annotationsN)	TYPE_CHECKINGAnyCallableDictOptionalSequenceSetTypeUnion)BaseMessage)BaseTool)convert_to_secret_strget_from_dict_or_env)Field	SecretStrmodel_validatorconvert_message_to_dict)
ChatOpenAI_import_tiktoken)is_openai_v1z%https://api.endpoints.anyscale.com/v1z#meta-llama/Meta-Llama-3-8B-Instructc                      s   e Zd ZU dZed-ddZed.ddZed/d
dZe	e
ddZded< 	 e	eddZded< 	 e	edZded< 	 dZded< 	 dZded< 	 edefd0ddZedded1d!d"Zd2d$d%Z	d3d4 fd+d,Z  ZS )5ChatAnyscalea  `Anyscale` Chat large language models.

    See https://www.anyscale.com/ for information about Anyscale.

    To use, you should have the ``openai`` python package installed, and the
    environment variable ``ANYSCALE_API_KEY`` set with your API key.
    Alternatively, you can use the anyscale_api_key keyword argument.

    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 ChatAnyscale
            chat = ChatAnyscale(model_name="meta-llama/Llama-2-7b-chat-hf")
    returnstrc                 C     dS )zReturn type of chat model.zanyscale-chat selfr   r   _/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/chat_models/anyscale.py	_llm_type>   s   zChatAnyscale._llm_typeDict[str, str]c                 C  s   ddiS )Nanyscale_api_keyANYSCALE_API_KEYr   r   r   r   r   
lc_secretsC   s   zChatAnyscale.lc_secretsboolc                 C  r   )NFr   )clsr   r   r   is_lc_serializableG   s   zChatAnyscale.is_lc_serializable defaultr   r"   model)r*   alias
model_nameanyscale_api_baseNOptional[str]anyscale_proxyzOptional[Set[str]]available_modelsSet[str]c              
   C  s   z	| pt jd } W n ty } ztd|d}~ww | d}tj|dd|  id}|jdkr<td	| d
|j dd | d D S )z'Get available models from Anyscale API.r#   zdAnyscale API key must be passed as keyword argument or set in environment variable ANYSCALE_API_KEY.Nz/modelsAuthorizationzBearer )headers   zError getting models from z: c                 S  s   h | ]}|d  qS )idr   ).0r+   r   r   r   	<setcomp>s       z4ChatAnyscale.get_available_models.<locals>.<setcomp>data)osenvironKeyError
ValueErrorrequestsgetstatus_codejson)r"   r.   eZ
models_urlZmodels_responser   r   r   get_available_modelsW   s.   


z!ChatAnyscale.get_available_modelsbefore)modevaluesdictr   c              
   C  sz  t t|dd|d< t|ddtd|d< t|dddd|d	< zd
dl}W n ty5 } ztd|d}~ww zFt rh|d  |d d}|dsV|jdi |j	j
|d< |dsg|jdi |j	j
|d< n|d |d< |d  |d< |j|d< W n ty } ztd|d}~ww d| vrt|d< |d }| |d  |d }||vrtd| d| d||d< |S )z?Validate that api key and python package exists in environment.r"   r#   r.   ZANYSCALE_API_BASEr)   r0   ZANYSCALE_PROXYr(   Zopenai_proxyr   NzTCould not import openai python package. Please install it with `pip install openai`.)Zapi_keybase_urlclientZasync_clientZopenai_api_baseZopenai_api_keyz`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-   zModel name z  not found in available models: .r1   r   )r   r   DEFAULT_API_BASEopenaiImportErrorr   Zget_secret_valuer@   ZOpenAIZchatZcompletionsZAsyncOpenAIZChatCompletionAttributeErrorr>   keysDEFAULT_MODELrD   )r&   rG   rM   rC   Zclient_paramsexcr-   r1   r   r   r   validate_environmentu   s   






z!ChatAnyscale.validate_environmenttuple[str, tiktoken.Encoding]c                 C  sd   t  }| jd ur| j}n| j}z
|d}W ||fS  ty1   td d}||}Y ||fS w )Nzgpt-3.5-turbo-0301z5Warning: model not found. Using cl100k_base encoding.Zcl100k_base)r   Ztiktoken_model_namer-   Zencoding_for_modelr=   loggerwarningZget_encoding)r   Z	tiktoken_r+   encodingr   r   r   _get_encoding_model   s   

z ChatAnyscale._get_encoding_modelmessageslist[BaseMessage]toolsCOptional[Sequence[Union[Dict[str, Any], Type, Callable, BaseTool]]]intc                   s   |dur	t d tjd dkrt |S |  \}}d}d}d}dd |D }|D ]"}	||7 }|	 D ]\}
}|t|	t
|7 }|
d	krL||7 }q5q+|d7 }|S )
zCalculate num tokens with tiktoken package.
        Official documentation: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_format_inputs_to_ChatGPT_models.ipynb
        NzECounting tokens in tool schemas is not yet supported. Ignoring tools.         r   c                 S  s   g | ]}t |qS r   r   )r7   mr   r   r   
<listcomp>   r9   z=ChatAnyscale.get_num_tokens_from_messages.<locals>.<listcomp>name)warningswarnsysversion_infosuperget_num_tokens_from_messagesrX   itemslenencoder   )r   rY   r[   r+   rW   Ztokens_per_messageZtokens_per_nameZ
num_tokensZmessages_dictmessagekeyvalue	__class__r   r   ri      s*   
z)ChatAnyscale.get_num_tokens_from_messages)r   r   )r   r!   )r   r%   )r"   r/   r.   r   r   r2   )rG   rH   r   r   )r   rT   )N)rY   rZ   r[   r\   r   r]   )__name__
__module____qualname____doc__propertyr    r$   classmethodr'   r   r   r"   __annotations__rQ   r-   rL   r.   r0   r1   staticmethodrD   r   rS   rX   ri   __classcell__r   r   rp   r   r   +   s8   
 
Nr   )+ru   
__future__r   loggingr;   rf   rd   typingr   r   r   r   r   r   r	   r
   r   r?   Zlangchain_core.messagesr   Zlangchain_core.toolsr   Zlangchain_core.utilsr   r   Zpydanticr   r   r   Z#langchain_community.adapters.openair   Z&langchain_community.chat_models.openair   r   Z langchain_community.utils.openair   Ztiktoken	getLoggerrr   rU   rL   rQ   r   r   r   r   r   <module>   s*    ,
