a
    bgo                     @  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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 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* ddl+m,Z,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4m5Z5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z; ddl<m=Z=m>Z> ddl?m@Z@ er^ddlAZAeBeCZDddddZEd/ddddddZFd0dddddddZGd d!d"d#d$d%ZHd&d&d&d'd(d)ZIed*d+d,d-G d.d deZJdS )1zOpenAI chat wrapper.    )annotationsN)TYPE_CHECKINGAnyAsyncIteratorCallableDictIteratorListMappingOptionalSequenceTupleTypeUnion)
deprecated)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)LanguageModelInput)BaseChatModelagenerate_from_streamgenerate_from_stream)create_base_retry_decorator)AIMessageChunkBaseMessageBaseMessageChunkChatMessageChunkFunctionMessageChunkHumanMessageChunkSystemMessageChunkToolMessageChunk)ChatGenerationChatGenerationChunk
ChatResult)Runnable)BaseTool)get_from_dict_or_envget_pydantic_field_namespre_init)	BaseModel
ConfigDictFieldmodel_validator)convert_dict_to_messageconvert_message_to_dict)is_openai_v1r   returnc                  C  s,   zdd l } W n ty&   tdY n0 | S )Nr   zCould not import tiktoken python package. This is needed in order to calculate get_token_ids. Please install it with `pip install tiktoken`.)tiktokenImportError)r1    r3   t/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/chat_models/openai.py_import_tiktokenF   s    
r5   
ChatOpenAIzHOptional[Union[AsyncCallbackManagerForLLMRun, CallbackManagerForLLMRun]]zCallable[[Any], Any])llmrun_managerr0   c                 C  s:   dd l }|jj|jj|jj|jj|jjg}t|| j|dS )Nr   )Zerror_typesmax_retriesr8   )	openaierrorTimeoutZAPIErrorZAPIConnectionErrorZRateLimitErrorZServiceUnavailableErrorr   r9   )r7   r8   r:   errorsr3   r3   r4   _create_retry_decoratorR   s    r>   'Optional[AsyncCallbackManagerForLLMRun])r7   r8   kwargsr0   c                   sV   t  r jjf i |I dH S t |d}|ddd fdd}|f i |I dH S )z0Use tenacity to retry the async completion call.Nr8   r   r@   r0   c                    s    j jf i | I d H S N)clientZacreater@   r7   r3   r4   _completion_with_retryq   s    z6acompletion_with_retry.<locals>._completion_with_retry)r.   async_clientcreater>   )r7   r8   r@   retry_decoratorrG   r3   rF   r4   acompletion_with_retryf   s    rK   zMapping[str, Any]zType[BaseMessageChunk]r   )_dictdefault_classr0   c                 C  s(  |  d}|  dpd}i }|  drVt| d }d|v rN|d d u 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 )Nrolecontent function_callnameZ
tool_callsuser)rO   Z	assistant)rO   additional_kwargssystemfunction)rO   rR   Ztooltool_call_id)rO   rW   )rO   rN   )getdictr   r   r   r   r   r   )rL   rM   rN   rO   rT   rQ   r3   r3   r4   _convert_delta_to_message_chunky   s.    




rZ   zUnion[int, dict])overall_token_usage	new_usager0   c                   s   t |tr8t  ts0tdt| dt  |  S t |tr~t  tshtdt| dt   fdd| D S tdt|  |S d S )Nz%Got different types for token usage: z and c                   s$   i | ]\}}|t  |d |qS )r   )_update_token_usagerX   ).0kvr[   r3   r4   
<dictcomp>   s   z'_update_token_usage.<locals>.<dictcomp>z!Unexpected type for token usage: )
isinstanceint
ValueErrortyperY   itemswarningswarn)r[   r\   r3   ra   r4   r]      s0    




r]   z0.0.10z1.0zlangchain_openai.ChatOpenAI)ZsinceZremovalZalternative_importc                      s  e Zd ZU dZeddddZeddddZed	dd
dZeddddZ	e
dd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< e
edZd	ed< e
dd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&< e
dd'dZd(ed)< e
d*d+Zd,ed-< d.Zded/< d0Zd,ed1< dZd2ed3< dZd ed4< dZd5ed6< dZd7ed8< dZd9ed:< edd;Z e!d<d=ed	dd>d?d@Z"e#dAdAd>dBdCZ$ed	ddDdEZ%ddFdddGdHdIZ&dJdKdLdMdNZ'ddOdPdFddQdRdSdTZ(ddOdPdFdUddVdWdXdYZ)dOdPdZd[d\d]Z*d^dVd_d`daZ+ddOdPdbddcdRdddeZ,ddOdPdbdUddVdWdfdgZ-ed	ddhdiZ.ed	ddjdkZ/ddPdd	dl fdmdnZ0edddodpZ1dqddrdsZ2ddtdu fdvdwZ3ddOdxd,dy fdzd{Z4dd|d dd}d~ fddZ5  Z6S )r6   a  `OpenAI` Chat large language models API.

    To use, you should have the ``openai`` python package installed, and the
    environment variable ``OPENAI_API_KEY`` set with 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 ChatOpenAI
            openai = ChatOpenAI(model="gpt-3.5-turbo")
    zDict[str, str]r/   c                 C  s   ddiS )Nopenai_api_keyOPENAI_API_KEYr3   selfr3   r3   r4   
lc_secrets   s    zChatOpenAI.lc_secretsz	List[str]c                 C  s   g dS )z*Get the namespace of the langchain object.)Z	langchainZchat_modelsr:   r3   clsr3   r3   r4   get_lc_namespace   s    zChatOpenAI.get_lc_namespacezDict[str, Any]c                 C  s8   i }| j r| j |d< | jr$| j|d< | jr4| j|d< |S )Nopenai_organizationopenai_api_baseopenai_proxy)rr   rs   rt   )rm   
attributesr3   r3   r4   lc_attributes   s    


zChatOpenAI.lc_attributesboolc                 C  s   dS )z9Return whether this model can be serialized by Langchain.Tr3   ro   r3   r3   r4   is_lc_serializable   s    zChatOpenAI.is_lc_serializableNT)defaultexcluder   rD   rH   gpt-3.5-turbomodel)ry   aliasstr
model_namegffffff?floattemperature)default_factorymodel_kwargsapi_keyzOptional[str]rj   base_urlrs   organizationrr   rt   timeoutz,Union[float, Tuple[float, float], Any, None]request_timeout   ry   rd   r9   F	streaming   nzOptional[int]
max_tokenstiktoken_model_namezUnion[Mapping[str, str], None]default_headersz!Union[Mapping[str, object], None]default_queryzUnion[Any, None]http_client)Zpopulate_by_namebefore)mode)valuesr0   c              
   C  s   t | }|di }t|D ]P}||v r8td| d||v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! z/ is not 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&   rX   listre   loggerwarningpopintersectionkeys)rp   r   Zall_required_field_namesextra
field_nameZinvalid_model_kwargsr3   r3   r4   build_extra  s*    
zChatOpenAI.build_extrar   c              	   C  sV  |d dk rt d|d dkr0|d r0t dt|dd|d< |d pZtd	pZtd
|d< |d pptd|d< t|dddd|d< zddl}W n ty   tdY n0 t r:|d |d |d |d |d |d |d |d d}|ds|jf i |j	j
|d< |dsR|jf i |j	j
|d< n|dsR|j|d< n |S )z?Validate that api key and python package exists in environment.r   r   zn must be at least 1.r   zn must be 1 when streaming.rj   rk   rr   ZOPENAI_ORG_IDZOPENAI_ORGANIZATIONrs   ZOPENAI_API_BASErt   ZOPENAI_PROXYrP   r   r   NzTCould not import openai python package. Please install it with `pip install openai`.r   r9   r   r   r   )r   r   r   r   r9   r   r   r   rD   rH   )re   r%   osgetenvr:   r2   r.   rX   ZOpenAIZchatZcompletionsZAsyncOpenAIZChatCompletion)rp   r   r:   Zclient_paramsr3   r3   r4   validate_environment3  s\    

zChatOpenAI.validate_environmentc                 C  sN   | j | j| j| jd| j}| jdur0| j|d< | jdurJt sJ| j|d< |S )z2Get the default parameters for calling OpenAI API.)r|   streamr   r   Nr   r   )r   r   r   r   r   r   r   r.   )rm   paramsr3   r3   r4   _default_paramsn  s    


zChatOpenAI._default_paramsz"Optional[CallbackManagerForLLMRun])r8   r@   r0   c                   sJ   t  r jjf i |S t |d}|ddd fdd}|f i |S )z*Use tenacity to retry the completion call.rA   r   rB   c                    s    j jf i | S rC   )rD   rI   rE   rl   r3   r4   rG     s    z@ChatOpenAI.completion_with_retry.<locals>._completion_with_retry)r.   rD   rI   r>   )rm   r8   r@   rJ   rG   r3   rl   r4   completion_with_retry~  s    z ChatOpenAI.completion_with_retryzList[Optional[dict]]rY   )llm_outputsr0   c           	      C  s   i }d }|D ]f}|d u rq|d }|d ur`|  D ],\}}||v rVt|| |||< q2|||< q2|d u r|d}q|| jd}|r||d< |S )Ntoken_usagesystem_fingerprint)r   r   )rg   r]   rX   r   )	rm   r   r[   r   outputr   r_   r`   combinedr3   r3   r4   _combine_llm_outputs  s&    

zChatOpenAI._combine_llm_outputszList[BaseMessage]zOptional[List[str]]zIterator[ChatGenerationChunk])messagesstopr8   r@   r0   c                 k  s   |  ||\}}i ||ddi}t}| jf ||d|D ]}t|tsT| }t|d dkrfq>|d d }	|	d d u rq>t|	d |}|	d}
|
d urt|
dnd }|j}t	||d	}|r|j
|j|d
 |V  q>d S )Nr   Tr   r8   choicesr   deltafinish_reasonr   messagegeneration_info)chunk)_create_message_dictsr   r   rc   rY   lenrZ   rX   	__class__r!   on_llm_new_tokentextrm   r   r   r8   r@   message_dictsr   Zdefault_chunk_classr   choicer   r   Zcg_chunkr3   r3   r4   _stream  s8    


zChatOpenAI._streamzOptional[bool]r"   )r   r   r8   r   r@   r0   c                 K  s   |d ur|n| j }|r6| j|f||d|}t|S | ||\}}	i |	|d ur\d|ini |}	| jf ||d|	}
| |
S N)r   r8   r   r   )r   r   r   r   r   _create_chat_resultrm   r   r   r8   r   r@   Zshould_streamZstream_iterr   r   responser3   r3   r4   	_generate  s0    zChatOpenAI._generatez+Tuple[List[Dict[str, Any]], Dict[str, Any]])r   r   r0   c                 C  s<   | j }|d ur&d|v 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 r3   r-   r^   mr3   r3   r4   
<listcomp>      z4ChatOpenAI._create_message_dicts.<locals>.<listcomp>)_client_paramsre   )rm   r   r   r   r   r3   r3   r4   r     s    z ChatOpenAI._create_message_dictszUnion[dict, BaseModel])r   r0   c           	      C  s   g }t |ts| }|d D ]J}t|d }t|dd}d|v rR|d |d< t||d}|| q|di }|| j|dd	d
}t||dS )Nr   r   r   r   Zlogprobsr   usager   rP   )r   r   r   )generations
llm_output)rc   rY   r,   rX   r    appendr   r"   )	rm   r   r   resr   r   genr   r   r3   r3   r4   r     s&    

zChatOpenAI._create_chat_resultr?   z"AsyncIterator[ChatGenerationChunk]c                 K s   |  ||\}}i ||ddi}t}t| f||d|I d H 2 z3 d H W }t|tsb| }t|d dkrtqD|d d }	|	d d u rqDt|	d |}|	d}
|
d urt|
dnd }|j}t	||d	}|r|j
|j|d
I d H  |V  qD6 d S )Nr   Tr   r   r   r   r   r   r   )tokenr   )r   r   rK   rc   rY   r   rZ   rX   r   r!   r   r   r   r3   r3   r4   _astream  s<    

zChatOpenAI._astreamc                   s   |d ur|n| j }|r<| j|f||d|}t|I d H S | ||\}}	i |	|d urbd|ini |}	t| f||d|	I d H }
| |
S r   )r   r   r   r   rK   r   r   r3   r3   r4   
_agenerate&  s4    zChatOpenAI._ageneratec                 C  s   i d| j i| jS )zGet the identifying parameters.r   )r   r   rl   r3   r3   r4   _identifying_params@  s    zChatOpenAI._identifying_paramsc                 C  sT   d| j i}t s(|| j| j| jd | jrFddl}| j| jd|_i | j	|S )z.Get the parameters used for the openai client.r|   )r   Zapi_baser   r   N)httphttps)
r   r.   updaterj   rs   rr   rt   r:   proxyr   )rm   Zopenai_credsr:   r3   r3   r4   r   E  s    zChatOpenAI._client_params)r   r@   r0   c                   s"   d| j it j|d| j|S )z,Get the parameters used to invoke the model.r|   )r   )r   super_get_invocation_paramsr   )rm   r   r@   r   r3   r4   r   Y  s    z!ChatOpenAI._get_invocation_paramsc                 C  s   dS )zReturn type of chat model.zopenai-chatr3   rl   r3   r3   r4   	_llm_typed  s    zChatOpenAI._llm_typezTuple[str, tiktoken.Encoding]c                 C  sz   t  }| jd ur| j}n | j}|dkr,d}n|dkr8d}z||}W n* typ   td d}||}Y n0 ||fS )Nr{   gpt-3.5-turbo-0301gpt-4z
gpt-4-0314z5Warning: model not found. Using cl100k_base encoding.Zcl100k_base)r5   r   r   Zencoding_for_modelKeyErrorr   r   Zget_encoding)rm   Z	tiktoken_r|   encodingr3   r3   r4   _get_encoding_modeli  s    

zChatOpenAI._get_encoding_modelz	List[int])r   r0   c                   s0   t jd dkrt |S |  \}}||S )z9Get the tokens present in the text with tiktoken package.r      )sysversion_infor   get_token_idsr   encode)rm   r   _Zencoding_modelr   r3   r4   r     s    zChatOpenAI.get_token_idszCOptional[Sequence[Union[Dict[str, Any], Type, Callable, BaseTool]]])r   toolsr0   c                   s   |durt d tjd dkr,t |S |  \}}|drLd}d}n.|ds`|d	rjd
}d}ntd| dd}dd |D }|D ]D}	||7 }|		 D ].\}
}|t
|t|7 }|
dkr||7 }qq|d
7 }|S )zCalculate num tokens for gpt-3.5-turbo and gpt-4 with tiktoken package.

        Official documentation: https://github.com/openai/openai-cookbook/blob/
        main/examples/How_to_format_inputs_to_ChatGPT_models.ipynbNzECounting tokens in tool schemas is not yet supported. Ignoring tools.r   r   r      r{   r      zFget_num_tokens_from_messages() is not presently implemented for model zy.See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.r   c                 S  s   g | ]}t |qS r3   r   r   r3   r3   r4   r     r   z;ChatOpenAI.get_num_tokens_from_messages.<locals>.<listcomp>rR   )rh   ri   r   r   r   get_num_tokens_from_messagesr   
startswithNotImplementedErrorrg   r   r   r~   )rm   r   r   r|   r   Ztokens_per_messageZtokens_per_nameZ
num_tokensZmessages_dictr   keyvaluer   r3   r4   r     s8    
z'ChatOpenAI.get_num_tokens_from_messagesz:Sequence[Union[Dict[str, Any], Type[BaseModel], Callable]]z)Runnable[LanguageModelInput, BaseMessage])	functionsrQ   r@   r0   c                   s   ddl m   fdd|D }|durt|dkr:td|d d |krhtd	| d
|d d  dd|i}i |d|i}t jf d|i|S )a  Bind functions (and other objects) to this chat model.

        Args:
            functions: A list of function definitions to bind to this chat model.
                Can be  a dictionary, pydantic model, or callable. Pydantic
                models and callables will be automatically converted to
                their schema dictionary representation.
            function_call: Which function to require the model to call.
                Must be the name of the single provided function or
                "auto" to automatically determine which function to call
                (if any).
            kwargs: Any additional parameters to pass to the
                :class:`~langchain.runnable.Runnable` constructor.
        r   convert_to_openai_functionc                   s   g | ]} |qS r3   r3   )r^   fnr   r3   r4   r     r   z-ChatOpenAI.bind_functions.<locals>.<listcomp>Nr   zGWhen specifying `function_call`, you must provide exactly one function.rR   zFunction call z3 was specified, but the only provided function was .rQ   r   )Z&langchain.chains.openai_functions.baser   r   re   r   bind)rm   r   rQ   r@   Zformatted_functionsZfunction_call_r   r   r4   bind_functions  s(    

zChatOpenAI.bind_functions)N)NN)NNN)NN)NNN)N)N)N)7__name__
__module____qualname____doc__propertyrn   classmethodrq   rv   rx   r*   rD   __annotations__rH   r   r   rY   r   rj   rs   rr   rt   r   r9   r   r   r   r   r   r   r   r)   Zmodel_configr+   r   r'   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r3   r3   r   r4   r6      s   

:   '     '     2 )N)N)Kr   
__future__r   loggingr   r   rh   typingr   r   r   r   r   r   r	   r
   r   r   r   r   r   Zlangchain_core._api.deprecationr   Zlangchain_core.callbacksr   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   Zlangchain_core.outputsr    r!   r"   Zlangchain_core.runnablesr#   Zlangchain_core.toolsr$   Zlangchain_core.utilsr%   r&   r'   Zpydanticr(   r)   r*   r+   Z#langchain_community.adapters.openair,   r-   Z langchain_community.utils.openair.   r1   	getLoggerr   r   r5   r>   rK   rZ   r]   r6   r3   r3   r3   r4   <module>   sB   <(

  