U
    h                     @  s  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mZ d dlmZ d dl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' d d
l(m)Z) d dl*m+Z+ d dl,m-Z- e.e/Z0dddddddZ1dddddZ2ddddddZ3ddddZ4d:dddd d!d"Z5d;dd#d$d$d%d&d'Z6d<dd(d$d$d%d)d*Z7G d+d, d,eZ8ed-d.d/d0G d1d2 d2e8Z9ed-d.d3d0G d4d5 d5e8Z:ed6d.d7d0G d8d9 d9eZ;dS )=    )annotationsN)AbstractSetAnyAsyncIteratorCallable
CollectionDictIteratorListLiteralMappingOptionalSetTupleUnion)
deprecated)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)BaseLLMcreate_base_retry_decorator)
GenerationGenerationChunk	LLMResult)Fieldroot_validator)get_from_dict_or_envget_pydantic_field_namespre_init)
get_fields)build_extra_kwargs)is_openai_v1zSet[str]Dict[str, Any]None)keysresponsetoken_usagereturnc                 C  sN   |  |d }|D ]6}||kr0|d | ||< q||  |d | 7  < qdS )zUpdate token usage.usageN)intersection)r#   r$   r%   Z_keys_to_use_key r*   C/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/llms/openai.pyupdate_token_usage-   s
    r,   r   )stream_responser&   c                 C  sR   | d st ddS t | d d d t| d d dd| d d ddd	d
S )z0Convert a stream response to a generation chunk.choices textr   r1   finish_reasonNlogprobsr2   r3   r1   generation_info)r   dictget)r-   r*   r*   r+   $_stream_response_to_generation_chunk9   s    
r9   )r$   r-   r&   c                 C  sd   | d d d  |d d d 7  < |d d  dd| d d d< |d d d | d d d< dS )z)Update response from the stream response.r.   r   r1   r2   Nr3   )r8   )r$   r-   r*   r*   r+   _update_responseH   s    $ r:   r&   c                   C  s   ddd d dgiS )Nr.   r/   r1   r2   r3   r*   r*   r*   r*   r+   _streaming_response_templateQ   s    r=   zUnion[BaseOpenAI, OpenAIChat]zHOptional[Union[AsyncCallbackManagerForLLMRun, CallbackManagerForLLMRun]]zCallable[[Any], Any])llmrun_managerr&   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_retriesr?   )	openaierrorTimeoutZAPIErrorZAPIConnectionErrorZRateLimitErrorZServiceUnavailableErrorr   r@   )r>   r?   rA   errorsr*   r*   r+   _create_retry_decorator]   s      rE   "Optional[CallbackManagerForLLMRun]r   )r>   r?   kwargsr&   c                   sB   t  r jjf |S t |d}|ddd fdd}|f |S )z*Use tenacity to retry the completion call.r?   r   rG   r&   c                    s    j jf | S N)clientcreaterG   r>   r*   r+   _completion_with_retry|   s    z5completion_with_retry.<locals>._completion_with_retry)r    rK   rL   rE   r>   r?   rG   Zretry_decoratorrO   r*   rN   r+   completion_with_retryq   s    rQ   'Optional[AsyncCallbackManagerForLLMRun]c                   sN   t  r jjf |I dH S t |d}|ddd fdd}|f |I dH S )z0Use tenacity to retry the async completion call.NrH   r   rI   c                    s    j jf | I d H S rJ   )rK   ZacreaterM   rN   r*   r+   rO      s    z6acompletion_with_retry.<locals>._completion_with_retry)r    async_clientrL   rE   rP   r*   rN   r+   acompletion_with_retry   s    rT   c                      sR  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< 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
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d0< d1Zded2< e
dd3dZd4ed5< e
ed'Zd6ed7< d8Zded9< d:Z ded;< e! Z"d<ed=< d>Z#d?ed@< dZ$d*edA< dZ%dBedC< dZ&dDedE< dZ'dFedG< ddHdI fdJdKZ(G dLdM dMZ)e*ddNd	d	dOdPdQZ+e,dRdRdOdSdTZ-ed	ddUdVZ.dddWdXddYdZd[d\Z/dddWd]dd^dZd_d`Z0dddWdXddadbdcddZ1dddWd]ddadbdedfZ2dd	ddWdgdhdidjZ3ddkddd	dld*dadmdndoZ4ed	ddpdqZ5edrddsdtZ6edddudvZ7ddwdx fdydzZ8e9ddd{d|d}Z:eddd~dZ;dddddZ<  Z=S )
BaseOpenAIz'Base OpenAI large language model class.zDict[str, str]r;   c                 C  s   ddiS )Nopenai_api_keyOPENAI_API_KEYr*   selfr*   r*   r+   
lc_secrets   s    zBaseOpenAI.lc_secrets	List[str]c                 C  s
   dddgS z*Get the namespace of the langchain object.Z	langchainZllmsrA   r*   clsr*   r*   r+   get_lc_namespace   s    zBaseOpenAI.get_lc_namespacer!   c                 C  s8   i }| j r| j |d< | jr$| j|d< | jr4| j|d< |S )Nopenai_api_baseopenai_organizationopenai_proxy)r`   ra   rb   )rY   
attributesr*   r*   r+   lc_attributes   s    


zBaseOpenAI.lc_attributesboolc                 C  s   dS )NTr*   r]   r*   r*   r+   is_lc_serializable   s    zBaseOpenAI.is_lc_serializableNTdefaultexcluder   rK   rS   gpt-3.5-turbo-instructmodelrh   aliasstr
model_namegffffff?floattemperature   int
max_tokens   top_pr   frequency_penaltypresence_penaltynbest_ofdefault_factorymodel_kwargsapi_keyOptional[str]rV   base_urlr`   organizationra   rb      
batch_sizetimeoutz,Union[float, Tuple[float, float], Any, None]request_timeoutzOptional[Dict[str, float]]
logit_bias   r@   F	streaming'Union[Literal['all'], AbstractSet[str]]allowed_specialall&Union[Literal['all'], Collection[str]]disallowed_specialtiktoken_model_namezUnion[Mapping[str, str], None]default_headersz!Union[Mapping[str, object], None]default_queryzUnion[Any, None]http_clientzUnion[OpenAIChat, BaseOpenAI])datar&   c                   sH   | dd}|ds |dr<d|kr<td tf |S t | S )zInitialize the OpenAI object.ro   r/   gpt-3.5-turbogpt-4z	-instructYou are trying to use a chat model. This way of initializing it is no longer supported. Instead, please use: `from langchain_community.chat_models import ChatOpenAI`)r8   
startswithwarningswarn
OpenAIChatsuper__new__)r^   r   ro   	__class__r*   r+   r      s    
zBaseOpenAI.__new__c                   @  s   e Zd ZdZdS )zBaseOpenAI.ConfigTN)__name__
__module____qualname__Zallow_population_by_field_namer*   r*   r*   r+   Config  s   r   prevaluesr&   c                 C  s(   t | }|di }t||||d< |S )>Build extra kwargs from additional params that were passed in.r}   )r   r8   r   )r^   r   all_required_field_namesextrar*   r*   r+   build_extra	  s      zBaseOpenAI.build_extrar   c              	   C  sh  |d dk rt d|d r0|d dkr0t d|d rL|d dkrLt dt|dd	|d< |d
 pltd|d
< t|dddd|d< |d ptdptd|d< zddl}W n tk
r   tdY nX t rL|d |d |d
 |d |d |d |d |d d}|ds,|jf |j	|d< |dsd|j
f |j	|d< n|dsd|j|d< n |S )?Validate that api key and python package exists in environment.ry   ru   n must be at least 1.r   !Cannot stream results when n > 1.rz   'Cannot stream results when best_of > 1.rV   rW   r`   OPENAI_API_BASErb   OPENAI_PROXYr/   rh   ra   OPENAI_ORG_IDOPENAI_ORGANIZATIONr   NTCould not import openai python package. Please install it with `pip install openai`.r   r@   r   r   r   )r~   r   r   r   r@   r   r   r   rK   rS   )
ValueErrorr   osgetenvrA   ImportErrorr    r8   OpenAIcompletionsZAsyncOpenAI
Completion)r^   r   rA   client_paramsr*   r*   r+   validate_environment  s`      


zBaseOpenAI.validate_environmentc                 C  sj   | j | j| j| j| j| jd}| jdk	r2| j|d< | jdk	rLt sL| j|d< | j	dkr`| j	|d< || j
S )2Get the default parameters for calling OpenAI API.)rq   rv   rw   rx   ry   r   Nrt   r   ru   rz   )rq   rv   rw   rx   ry   r   rt   r   r    rz   r}   )rY   Znormal_paramsr*   r*   r+   _default_paramsL  s    	




zBaseOpenAI._default_paramsOptional[List[str]]rF   Iterator[GenerationChunk]promptstopr?   rG   r&   c                 k  s   | j |ddi}| ||g| t| f||d|D ]N}t|tsL| }t|}|r~|j|j|| j|j	rv|j	d nd d |V  q6d S NstreamTr   r?   r3   )chunkverboser3   )
_invocation_paramsget_sub_promptsrQ   
isinstancer7   r9   on_llm_new_tokenr1   r   r6   rY   r   r   r?   rG   paramsstream_respr   r*   r*   r+   _streamd  s.     

zBaseOpenAI._streamrR   AsyncIterator[GenerationChunk]c                 K s   | j |ddi}| ||g| t| f||d|I d H 2 z\3 d H W }t|tsZ| }t|}|r|j|j|| j|j	r|j	d nd dI d H  |V  q<6 d S r   )
r   r   rT   r   r7   r9   r   r1   r   r6   r   r*   r*   r+   _astream~  s.     
zBaseOpenAI._astreamr   promptsr   r?   rG   r&   c                 K  s6  | j }||}| |||}g }i }dddh}	d}
|D ]}| jrt|dkrTtdd}| j|d ||f|D ]}|dkr|}qn||7 }qn|dk	st||j|j	r|j	
dnd|j	r|j	
d	ndd
 q6t| f||d|}t|ts| }||d  t|	|| |
s6|
d}
q6| j|||||
dS )at  Call out to OpenAI's endpoint with k unique prompts.

        Args:
            prompts: The prompts to pass into the model.
            stop: Optional list of stop words to use when generating.

        Returns:
            The full LLM output.

        Example:
            .. code-block:: python

                response = openai.generate(["Tell me a joke."])
        completion_tokensprompt_tokenstotal_tokensNru   ,Cannot stream results with multiple prompts.r   r2   r3   r<   r   r.   system_fingerprintr   )r   r   r   lenr   r   AssertionErrorappendr1   r6   r8   rQ   r   r7   extendr,   create_llm_resultrY   r   r   r?   rG   r   sub_promptsr.   r%   _keysr   Z_prompts
generationr   r$   r*   r*   r+   	_generate  s`    

 
zBaseOpenAI._generatec                   s:  | j }||}| |||}g }i }dddh}	d}
|D ]}| jrt|dkrTtdd}| j|d ||f|2 z"3 dH W }|dkr|}qn||7 }qn6 |dk	st||j|j	r|j	
dnd|j	r|j	
d	ndd
 q6t| f||d|I dH }t|ts
| }||d  t|	|| q6| j|||||
dS )z:Call out to OpenAI's endpoint async with k unique prompts.r   r   r   Nru   r   r   r2   r3   r<   r   r.   r   )r   r   r   r   r   r   r   r   r1   r6   r8   rT   r   r7   r   r,   r   r   r*   r*   r+   
_agenerate  sh    
   zBaseOpenAI._ageneratezList[List[str]])r   r   r   r&   c                   sx   |dk	r d|krt d||d< |d dkrRt dkr@t d d |d<  fd	d
tdt jD }|S )z!Get the sub prompts for llm call.Nr   2`stop` found in both the input and default params.rt   ru   z7max_tokens set to -1 not supported for multiple inputs.r   c                   s   g | ]} ||j   qS r*   )r   ).0ir   rY   r*   r+   
<listcomp>.  s   z.BaseOpenAI.get_sub_prompts.<locals>.<listcomp>)r   r   max_tokens_for_promptranger   )rY   r   r   r   r   r*   r   r+   r     s    zBaseOpenAI.get_sub_promptsr   zDict[str, int])r.   r   r   r%   r   r&   c                C  st   g }| d| j}t|D ]4\}}	||| |d |  }
|dd |
D  q|| jd}|rh||d< t||dS )z2Create the LLMResult from the choices and prompts.ry   ru   c              	   S  s0   g | ](}t |d  t|d|dddqS )r1   r2   r3   r4   r5   )r   r7   r8   )r   choicer*   r*   r+   r   C  s   z0BaseOpenAI.create_llm_result.<locals>.<listcomp>r%   ro   r   generations
llm_output)r8   ry   	enumerater   ro   r   )rY   r.   r   r   r%   r   r   ry   r   _Zsub_choicesr   r*   r*   r+   r   4  s    
zBaseOpenAI.create_llm_resultc                 C  sJ   i }t  s"|| j| j| jd | jr@ddl}| j| jd|_|| jS )z,Get the parameters used to invoke the model.)r~   api_baser   r   Nhttphttps)	r    updaterV   r`   ra   rb   rA   proxyr   )rY   Zopenai_credsrA   r*   r*   r+   r   S  s    zBaseOpenAI._invocation_paramsMapping[str, Any]c                 C  s   d| j i| jS zGet the identifying parameters.ro   ro   r   rX   r*   r*   r+   _identifying_paramse  s    zBaseOpenAI._identifying_paramsc                 C  s   dS )Return type of llm.rA   r*   rX   r*   r*   r+   	_llm_typej  s    zBaseOpenAI._llm_type	List[int]r1   r&   c                   s   t jd dk rt |S zddl}W n tk
rB   tdY nX | jpN| j}z||}W n, t	k
r   t
d d}||}Y nX |j|| j| jdS )	-Get the token IDs using the tiktoken package.ru      r   NCould not import tiktoken python package. This is needed in order to calculate get_num_tokens. Please install it with `pip install tiktoken`.z5Warning: model not found. Using cl100k_base encoding.Zcl100k_baser   r   )sysversion_infor   get_num_tokenstiktokenr   r   ro   encoding_for_modelKeyErrorloggerwarningZget_encodingencoder   r   )rY   r1   r
  ro   encrk   r   r*   r+   get_token_idso  s(    

zBaseOpenAI.get_token_ids)	modelnamer&   c                 C  s   dddddddddddddddddddddddd	d	d
d
d}d| krR|  dd } || d}|dkrtd|  dd|  |S )ao  Calculate the maximum number of tokens possible to generate for a model.

        Args:
            modelname: The modelname we want to know the context size for.

        Returns:
            The maximum context size

        Example:
            .. code-block:: python

                max_tokens = openai.modelname_to_contextsize("gpt-3.5-turbo-instruct")
        i  i    i   i   i@  i  i  i  iA  i   )zgpt-4ozgpt-4o-2024-05-13r   z
gpt-4-0314z
gpt-4-0613z	gpt-4-32kzgpt-4-32k-0314zgpt-4-32k-0613r   zgpt-3.5-turbo-0301zgpt-3.5-turbo-0613zgpt-3.5-turbo-16kzgpt-3.5-turbo-16k-0613rj   ztext-ada-001Zadaztext-babbage-001Zbabbageztext-curie-001ZcurieZdavinciztext-davinci-003ztext-davinci-002zcode-davinci-002zcode-davinci-001zcode-cushman-002zcode-cushman-001zft-:r   NzUnknown model: z=. Please provide a valid OpenAI model name.Known models are: z, )splitr8   r   joinr#   )r  Zmodel_token_mappingZcontext_sizer*   r*   r+   modelname_to_contextsize  sL    
z#BaseOpenAI.modelname_to_contextsizec                 C  s   |  | jS )z$Get max context size for this model.)r  ro   rX   r*   r*   r+   max_context_size  s    zBaseOpenAI.max_context_size)r   r&   c                 C  s   |  |}| j| S )ao  Calculate the maximum number of tokens possible to generate for a prompt.

        Args:
            prompt: The prompt to pass into the model.

        Returns:
            The maximum number of tokens to generate for a prompt.

        Example:
            .. code-block:: python

                max_tokens = openai.max_token_for_prompt("Tell me a joke.")
        )r	  r  )rY   r   Z
num_tokensr*   r*   r+   r     s    
z BaseOpenAI.max_tokens_for_prompt)NN)NN)NN)NN)N)>r   r   r   __doc__propertyrZ   classmethodr_   rd   rf   r   rK   __annotations__rS   ro   rq   rt   rv   rw   rx   ry   rz   r7   r}   rV   r`   ra   rb   r   r   r   r@   r   setr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  staticmethodr  r  r   __classcell__r*   r*   r   r+   rU      s   
 
	8      N  > :rU   z0.0.10z1.0zlangchain_openai.OpenAI)ZsinceZremovalZalternative_importc                      s<   e Zd ZdZeddddZedd fddZ  ZS )	r   a  OpenAI large language models.

    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.llms import OpenAI
            openai = OpenAI(model_name="gpt-3.5-turbo-instruct")
    r[   r;   c                 C  s
   dddgS r\   r*   r]   r*   r*   r+   r_     s    zOpenAI.get_lc_namespacer!   c                   s   d| j it jS )Nrk   )ro   r   r   rX   r   r*   r+   r     s    zOpenAI._invocation_params)	r   r   r   r  r  r_   r  r   r  r*   r*   r   r+   r     s
   r   zlangchain_openai.AzureOpenAIc                      s  e Zd ZU dZ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< dZded< dZd
ed< dZded< eddddZedddddZedd fddZed d fd!d"Zed
dd#d$Zed dd%d&Z  ZS )'AzureOpenAIa   Azure-specific OpenAI large language models.

    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.llms import AzureOpenAI

            openai = AzureOpenAI(model_name="gpt-3.5-turbo-instruct")
    NzUnion[str, None]azure_endpointazure_deploymentrl   deployment_namer/   api_versionrn   openai_api_versionr~   rV   azure_ad_tokenzUnion[Callable[[], str], None]azure_ad_token_provideropenai_api_typeTre   validate_base_urlr[   r;   c                 C  s
   dddgS r\   r*   r]   r*   r*   r+   r_   1  s    zAzureOpenAI.get_lc_namespacer   r   c                 C  s~  |d dk rt d|d r0|d dkr0t d|d rL|d dkrLt d|d pftd	pftd
|d< |d p|td|d< |d ptd|d< |d ptd|d< t|dddd|d< |d ptdptd|d< |d ptd|d< t|dddd|d< zddl}W n tk
r6   tdY nX t rp|d }|r|d  rd!|kr|d d"d! |d< t	d#| d$|d  d% |d& rt	d' |d& |d krt	d(| d$|d  d% |d  d)|d&  7  < d|d&< |d |d |d& |d |d |d* |d |d |d+ |d, |d- |d. |d/ d0}|j
f |j|d1< |jf |j|d2< n
|j|d1< |S )3r   ry   ru   r   r   r   rz   r   rV   ZAZURE_OPENAI_API_KEYrW   r   ZAZURE_OPENAI_ENDPOINTr%  ZAZURE_OPENAI_AD_TOKENr`   r   rb   r   r/   r   ra   r   r   r$  ZOPENAI_API_VERSIONr'  ZOPENAI_API_TYPEazurer   Nr   r(  z/openai/zAs of openai>=1.0.0, Azure endpoints should be specified via the `azure_endpoint` param not `openai_api_base` (or alias `base_url`). Updating `openai_api_base` from z to .r"  zAs of openai>=1.0.0, if `deployment_name` (or alias `azure_deployment`) is specified then `openai_api_base` (or alias `base_url`) should not be. Instead use `deployment_name` (or alias `azure_deployment`) and `azure_endpoint`.zAs of openai>=1.0.0, if `openai_api_base` (or alias `base_url`) is specified it is expected to be of the form https://example-resource.azure.openai.com/openai/deployments/example-deployment. Updating z/deployments/r&  r   r@   r   r   r   )r#  r   r!  r~   r%  r&  r   r   r   r@   r   r   r   rK   rS   )r   r   r   r   rA   r   r    rstripr   r   r  r   ZAsyncAzureOpenAIr   )r^   r   rA   r`   r   r*   r*   r+   r   6  s    
   





z AzureOpenAI.validate_environmentr   c                   s   d| j it jS )Nr"  )r"  r   r   rX   r   r*   r+   r     s    zAzureOpenAI._identifying_paramsr!   c                   s0   t  rd| ji}n| j| j| jd}|t jS )Nrk   )ZengineZapi_typer#  )r    r"  r'  r$  r   r   )rY   Zopenai_paramsr   r*   r+   r     s    zAzureOpenAI._invocation_paramsc                 C  s   dS )r   r)  r*   rX   r*   r*   r+   r     s    zAzureOpenAI._llm_typec                 C  s   | j | jdS )Nr'  r$  r-  rX   r*   r*   r+   rd     s    zAzureOpenAI.lc_attributes)r   r   r   r  r   r  r   r"  r$  rV   r%  r&  r'  r(  r  r_   r   r   r  r   r   r   rd   r  r*   r*   r   r+   r    s*   
pr  z0.0.1zlangchain_openai.ChatOpenAIc                      s  e Zd ZU dZ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< dZded< dZded< eedZded< dZded< e Zded< dZd ed!< edd"ddd#d$d%Zed&d&d#d'd(Zedd)d*d+ZdJd,d-d.d/d0d1ZdKd	d-d2dd3d4d5d6ZdLd	d-d7dd8d4d9d:ZdMd,d-d2dd;d<d=d>ZdNd,d-d7dd;d<d?d@ZedAd)dBdCZ ed	d)dDdEZ!d	dFdG fdHdIZ"  Z#S )Or   a  OpenAI Chat large language models.

    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.llms import OpenAIChat
            openaichat = OpenAIChat(model_name="gpt-3.5-turbo")
    NTrg   r   rK   rS   r   rn   ro   r{   r!   r}   r~   rl   r   rV   r   r`   rb      rs   r@   r
   prefix_messagesFre   r   r   r   r   r   r   r   r   c                 C  sj   dd t |  D }|di }t|D ]2}||kr*||krNtd| d||||< q*||d< |S )r   c                 S  s   h | ]
}|j qS r*   )rm   )r   fieldr*   r*   r+   	<setcomp>  s     z)OpenAIChat.build_extra.<locals>.<setcomp>r}   zFound z supplied twice.)r   r   r8   listr   pop)r^   r   r   r   
field_namer*   r*   r+   r     s    zOpenAIChat.build_extrar   c                 C  s   t |dd}t |dddd}t |dddd}t |d	d
dd}z6ddl}||_|rV||_|r`||_|rp||d|_W n tk
r   tdY nX z|j|d< W n tk
r   t	dY nX t
d |S )r   rV   rW   r`   r   r/   r   rb   r   ra   r   r   Nr   r   rK   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   )r   rA   r~   r   r   r   r   ZChatCompletionAttributeErrorr   r   r   )r^   r   rV   r`   rb   ra   rA   r*   r*   r+   r     s\         

zOpenAIChat.validate_environmentr;   c                 C  s   | j S )r   )r}   rX   r*   r*   r+   r   8  s    zOpenAIChat._default_paramsr[   r   r   )r   r   r&   c                 C  s|   t |dkrtd| | jd|d dg }d| ji| j}|d k	r`d|krXtd||d< |d	d
krt|d	= ||fS )Nru   z6OpenAIChat currently only supports single prompt, got userr   )rolecontentrk   r   r   rt   r   )r   r   r/  ro   r   r8   )rY   r   r   messagesr   r*   r*   r+   _get_chat_params=  s    zOpenAIChat._get_chat_paramsrF   r   r   c           
      k  s   |  |g|\}}||ddi}t| f||d|D ]P}t|tsL| }|d d d dd}t|d	}	|r|j||	d
 |	V  q6d S Nr   Tr9  r?   r.   r   deltar8  r/   r0   )r   )r:  rQ   r   r7   r8   r   r   
rY   r   r   r?   rG   r9  r   r   tokenr   r*   r*   r+   r   O  s"     


zOpenAIChat._streamrR   r   c           
      K s   |  |g|\}}||ddi}t| f||d|I d H 2 z^3 d H W }t|tsZ| }|d d d dd}t|d	}	|r|j||	d
I d H  |	V  q<6 d S r;  )r:  rT   r   r7   r8   r   r   r>  r*   r*   r+   r   c  s"     

zOpenAIChat._astreamr   r   c                 K  s   | j rVd }| j|d ||f|D ]}|d kr2|}q ||7 }q |d k	sHtt|ggdS | ||\}}||}t| f||d|}	t|	ts|	 }	|	d | jd}
tt	|	d d d d d	gg|
d
S Nr   )r   r<  r'   r   r.   messager8  r0   r   )
r   r   r   r   r:  rQ   r   r7   ro   r   rY   r   r   r?   rG   r   r   r9  r   Zfull_responser   r*   r*   r+   r   w  s8    
 
zOpenAIChat._generatec                   s   | j r`d }| j|d ||f|2 z"3 d H W }|d kr:|}q ||7 }q 6 |d k	sRtt|ggdS | ||\}}||}t| f||d|I d H }	t|	ts|	 }	|	d | jd}
tt	|	d d d d d	gg|
d
S r@  )
r   r   r   r   r:  rT   r   r7   ro   r   rB  r*   r*   r+   r     s8    " 
zOpenAIChat._agenerater   c                 C  s   d| j i| jS r   r   rX   r*   r*   r+   r     s    zOpenAIChat._identifying_paramsc                 C  s   dS )r   zopenai-chatr*   rX   r*   r*   r+   r     s    zOpenAIChat._llm_typer  r  c                   sd   t jd dk rt |S zddl}W n tk
rB   tdY nX || j}|j|| j	| j
dS )r  ru   r  r   Nr  r  )r  r  r   r  r
  r   r  ro   r  r   r   )rY   r1   r
  r  r   r*   r+   r    s    
zOpenAIChat.get_token_ids)N)NN)NN)NN)NN)$r   r   r   r  r   rK   r  rS   ro   r7   r}   rV   r`   rb   r@   r2  r/  r   r  r   r   r   r   r   r   r  r   r:  r   r   r   r   r   r   r  r  r*   r*   r   r+   r     sL   
2       &  #r   )N)N)N)<
__future__r   loggingr   r  r   typingr   r   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_models.llmsr   r   Zlangchain_core.outputsr   r   r   Zlangchain_core.pydantic_v1r   r   Zlangchain_core.utilsr   r   r   Zlangchain_core.utils.pydanticr   Zlangchain_core.utils.utilsr   Z langchain_community.utils.openair    	getLoggerr   r  r,   r9   r:   r=   rE   rQ   rT   rU   r   r  r   r*   r*   r*   r+   <module>   sZ   @
	       K   M