o
    }!gі                     @   s8  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mZmZmZ d dlZd dlZd dlm  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%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ d dl,m-Z-m.Z. d dl/m0Z0 d dl1m2Z2 d dl3m4Z4m5Z5 d d	l6m7Z7 d d
l8m9Z9m:Z: d dl;m<Z< d dl=m>Z> d dl?m@Z@ d dlAmBZBmCZC d dlDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQ d dlRmSZSmTZT d dlRmUZV d dlWmXZXmYZYmZZZ e[e\Z]erd dl^m_Z_ dZ`dedef dedef fddZaeG dd deZbde$ddfddZcG dd  d e7ZUdS )!    N)TYPE_CHECKINGAnyAsyncGenerator	AwaitableCallableDict	GeneratorListLiteralOptionalProtocolSequenceTypeUnioncastget_argsruntime_checkable)achat_to_completion_decoratoracompletion_to_chat_decorator$astream_chat_to_completion_decorator$astream_completion_to_chat_decoratorchat_to_completion_decoratorcompletion_to_chat_decorator#stream_chat_to_completion_decorator#stream_completion_to_chat_decorator)	ChatMessageChatResponseChatResponseAsyncGenChatResponseGenCompletionResponseCompletionResponseAsyncGenCompletionResponseGenLLMMetadataMessageRole)FieldPrivateAttr)CallbackManager)DEFAULT_TEMPERATURE)llm_chat_callbackllm_completion_callback)FunctionCallingLLM)ToolSelectionModel)parse_partial_json)PromptTemplate)FlexibleModel)BaseOutputParserPydanticProgramMode)	O1_MODELSOpenAIToolCallcreate_retry_decoratorfrom_openai_completion_logprobsfrom_openai_messagefrom_openai_token_logprobsis_chat_modelis_function_calling_modelopenai_modelname_to_contextsizeresolve_openai_credentialsresolve_tool_choiceto_openai_message_dictsupdate_tool_calls)AsyncOpenAIAzureOpenAI)OpenAI)ChatCompletionChunkChoiceDeltaChoiceDeltaToolCall)BaseToolzgpt-3.5-turbof.returnc                    s(   t  dtdtdtf fdd}|S )NargskwargsrG   c                    sV   t | dd}|dkr | g|R i |S t|ddddd}| | g|R i |S )Nmax_retriesr   T<         )rJ   random_exponentialstop_after_delay_secondsmin_secondsmax_seconds)getattrr4   )selfrH   rI   rJ   retryrF    ^/mnt/skqttb/ctump_chatbot/chatbot/lib/python3.10/site-packages/llama_index/llms/openai/base.pywrappera   s   z$llm_retry_decorator.<locals>.wrapper)	functoolswrapsr   )rF   rX   rV   rU   rW   llm_retry_decorator`   s   r[   c                   @   s&   e Zd ZdZdedee fddZdS )	TokenizerzBTokenizers support an encode function that returns a list of ints.textrG   c                 C   s   d S NrV   )rS   r]   rV   rV   rW   encodew   s   zTokenizer.encodeN)__name__
__module____qualname____doc__strr	   intr_   rV   rV   rV   rW   r\   s   s    r\   responsec                 C   s6   | j jdg }t|dkr|d g| j jd< d S d S )N
tool_callsrL   r   )messageadditional_kwargsgetlen)rf   rg   rV   rV   rW   force_single_tool_call{   s   rl   c                7       s  e Zd ZU dZeeddZeed< ee	ddddZ
eed	< ed
ddZee ed< edddZee ed< edddddZeed< eeddZeeef ed< eddddZeed< eddddZeed< edd dZeeeef  ed!< ed"d#dZeed$< edd%dZeed&< ed'd(Zeed)< ed*d(Zeed+< ed,d-dZeed.< edd/dZeed0  ed1< edd2dZ ee!e  ed3< edd4dZ"eeeef  ed5< e# Z$ee% ed6< e# Z&ee' ed7< e# Z(ee)j* ed8< e# Z+ee)j, ed9< ee	ddddd"dddddddddddde-j.dd,dddfded	edee deeeef  deded$ed&ee d)ee d+ee d:ee/ d!eeeef  d;ee)j* d<ee)j, d=ee% d>ee' d?ee d@ee0e1e2 gef  dAee0egef  dBe-dCee3 d.ed1eed0  d3ee!e  d5eeeef  dDedEdf6 fdFdGZ4dEe%fdHdIZ5dEe'fdJdKZ6dEefdLdMZ7dEefdNdOZ8e9dEefdPdQZ:e;dEee< fdRdSZ=e;dEe>fdTdUZ?e@ dVe1e2 dDedEeAfdWdXZBe@ dVe1e2 dDedEeCfdYdZZDeE 	,dd[ed\edDedEeFfd]d^ZGeE 	,dd[ed\edDedEeHfd_d`ZIdDeeef dEefdadbZJddcedEeeef fdddeZKdDedEeeef fdfdgZLeMdVe1e2 dDedEeAfdhdiZNeMdVe1e2 dDedEeCfdjdkZOeMd[edDedEeFfdldmZPeMd[edDedEeHfdndoZQdpeeef d[edEdfdqdrZRdsedEefdtduZSe@ dVe1e2 dDedEeAfdvdwZTe@ dVe1e2 dDedEeUfdxdyZVeE 	,dd[ed\edDedEeFfdzd{ZWeE 	,dd[ed\edDedEeXfd|d}ZYeMdVe1e2 dDedEeAfd~dZZeMdVe1e2 dDedEeUfddZ[eMd[edDedEeFfddZ\eMd[edDedEeXfddZ]			,	,		dde1d dee^ee2f  dee!e2  dedede^eef d.ee dDedEeeef fddZ_	,ddeAde1d dedDedEeAf
ddZ`	"ddddedDedEe!ea fddZbecjd	ddeeef d[egdeeeef  dedEeff
 fddZhecjd	ddeeef d[egdeeeef  dedEeff
 fddZiecjd	ddeeef d[egdeeeef  dedEeje^efekf ddf f
 fddZlecjd	ddeeef d[egdeeeef  dedEeme^efekf df f
 fddZn  ZoS )rA   a  
    OpenAI LLM.

    Args:
        model: name of the OpenAI model to use.
        temperature: a float from 0 to 1 controlling randomness in generation; higher will lead to more creative, less deterministic responses.
        max_tokens: the maximum number of tokens to generate.
        additional_kwargs: Add additional parameters to OpenAI request body.
        max_retries: How many times to retry the API call if it fails.
        timeout: How long to wait, in seconds, for an API call before failing.
        reuse_client: Reuse the OpenAI client between requests. When doing anything with large volumes of async API calls, setting this to false can improve stability.
        api_key: Your OpenAI api key
        api_base: The base URL of the API to call
        api_version: the version of the API to call
        callback_manager: the callback manager is used for observability.
        default_headers: override the default headers for API requests.
        http_client: pass in your own httpx.Client instance.
        async_http_client: pass in your own httpx.AsyncClient instance.

    Examples:
        `pip install llama-index-llms-openai`

        ```python
        import os
        import openai

        os.environ["OPENAI_API_KEY"] = "sk-..."
        openai.api_key = os.environ["OPENAI_API_KEY"]

        from llama_index.llms.openai import OpenAI

        llm = OpenAI(model="gpt-3.5-turbo")

        stream = llm.stream("Hi, write a short story")

        for r in stream:
            print(r.delta, end="")
        ```
    zThe OpenAI model to use.)defaultdescriptionmodelz)The temperature to use during generation.g        g       @)rm   rn   geletemperaturez)The maximum number of tokens to generate.r   )rn   gt
max_tokensz%Whether to return logprobs per token.N)rn   rm   logprobsz,The number of top token log probs to return.rM   )rn   rm   rp   rq   top_logprobsz%Additional kwargs for the OpenAI API.)default_factoryrn   ri      z"The maximum number of API retries.)rm   rn   rp   rJ   g      N@z*The timeout, in seconds, for API requests.timeoutz%The default headers for API requests.default_headersTzReuse the OpenAI client between requests. When doing anything with large volumes of async API calls, setting this to false can improve stability.reuse_clientzThe OpenAI API key.api_keyzThe base URL for OpenAI API.)rn   api_basezThe API version for OpenAI API.api_versionFz<Whether to use strict mode for invoking tools/using schemas.strictz'The effort to use for reasoning models.)lowmediumhighreasoning_effortz+The output modalities to use for the model.
modalitiesz-The audio configuration to use for the model.audio_config_client_aclient_http_client_async_http_clientcallback_managerhttp_clientasync_http_clientopenai_clientasync_openai_clientsystem_promptmessages_to_promptcompletion_to_promptpydantic_program_modeoutput_parserrI   rG   c                    s   d|v r|d }|d= |pi }t ||	|
d\}}	}
|tv rd}t jdi d|d|d|d|d|d	|d
|d|
d|	d|d|d|d|d|d|d|d|d|d|d|d|| || _|| _|| _|| _d S )Nmax_new_tokens)r|   r}   r~   g      ?ro   rr   rt   ri   rJ   r   r|   r~   r}   ry   r{   rz   r   r   r   r   r   r   r   r   r   rV   )r;   r2   super__init__r   r   r   r   )rS   ro   rr   rt   ri   rJ   ry   r{   r|   r}   r~   r   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   rI   	__class__rV   rW   r      sv   	

zOpenAI.__init__c                 C   s<   | j stdi |  S | jd u rtdi |  | _| jS )NrV   )r{   
SyncOpenAI_get_credential_kwargsr   rS   rV   rV   rW   _get_client?  s
   
zOpenAI._get_clientc                 C   sD   | j stdi | jddS | jd u rtdi | jdd| _| jS )NT)is_asyncrV   )r{   r?   r   r   r   rV   rV   rW   _get_aclientG  s
   
zOpenAI._get_aclientc                 C   s<   | j }d|v r|dd }|S |dr|dd }|S )Nzft-:r   zft:rL   )ro   split
startswith)rS   
model_namerV   rV   rW   _get_model_nameO  s   
zOpenAI._get_model_namec                 C   s   t |  tS r^   )
isinstancer   r@   r   rV   rV   rW   _is_azure_clientW  s   zOpenAI._is_azure_clientc                 C   s   dS )N
openai_llmrV   )clsrV   rV   rW   
class_nameZ  s   zOpenAI.class_namec                 C   s   t |  S )z
        Get a tokenizer for this model, or None if a tokenizing method is unknown.

        OpenAI can do this using the tiktoken package, subclasses may not have
        this convenience.
        )tiktokenencoding_for_modelr   r   rV   rV   rW   
_tokenizer^  s   zOpenAI._tokenizerc                 C   sN   t t|  | jp
dt|  dt|  d| j| jtv r"tj	dS tj
dS )Nro   )context_window
num_outputr8   r9   r   system_role)r"   r:   r   rt   r8   r9   ro   r2   r#   USERSYSTEMr   rV   rV   rW   metadatah  s   

zOpenAI.metadatamessagesc                 K   ,   |  |r	| j}nt| j}||fi |S r^   )_use_chat_completions_chatr   	_complete)rS   r   rI   chat_fnrV   rV   rW   chatx  s   

zOpenAI.chatc                 K   r   r^   )r   _stream_chatr   _stream_complete)rS   r   rI   stream_chat_fnrV   rV   rW   stream_chat  s   

zOpenAI.stream_chatprompt	formattedc                 K   sD   | j rd| j v rtd| |rt| j}n| j}||fi |S Naudioz>Audio is not supported for completion. Use chat/achat instead.)r   
ValueErrorr   r   r   r   )rS   r   r   rI   complete_fnrV   rV   rW   complete  s   
zOpenAI.completec                 K   s,   |  |rt| j}n| j}||fi |S r^   )r   r   r   r   )rS   r   r   rI   stream_complete_fnrV   rV   rW   stream_complete  s   
zOpenAI.stream_completec                 C   s   d|v r|d S | j jS )Nuse_chat_completions)r   r8   )rS   rI   rV   rV   rW   r     s   zOpenAI._use_chat_completionsr   c                 C   s,   | j | j| j| j| j|r| jdS | jdS )N)r|   base_urlrJ   ry   rz   r   )r|   r}   rJ   ry   rz   r   r   )rS   r   rV   rV   rW   r     s   zOpenAI._get_credential_kwargsc                 K   s  | j | jd|}| jd ur| j|d< | jd ur1| jdu r1| jjr,| j|d< | j|d< n| j|d< i || j}d|vrCd|v rC|d= | j tv r_|	dd ur_|	d|d |d< |
dd  | j tv rn| jd urn| j|d	< | jd urx| j|d
< | jd ur| j|d< |S )N)ro   rr   rt   Tru   rv   streamstream_optionsmax_completion_tokensr   r   r   )ro   rr   rt   ru   r   r8   rv   ri   r2   rj   popr   r   r   )rS   rI   base_kwargs
all_kwargsrV   rV   rW   _get_model_kwargs  s.   








zOpenAI._get_model_kwargsc           
      K   s   |   }t|| jd}| jr"|jjjd|dd| jdi |}n%| |jjjd|dd| jdi |}W d    n1 sBw   Y  |jd j	}t
|| jpTdgd}|jd j}d }	|ri|jrit|j}	t|||	| |dS 	Nr   F)r   r   r   r]   )r   )rh   rawru   ri   rV   )r   r=   ro   r{   r   completionscreater   choicesrh   r6   r   ru   contentr7   r   _get_response_token_counts)
rS   r   rI   clientmessage_dictsrf   openai_messagerh   openai_token_logprobsru   rV   rV   rW   r     sD   



zOpenAI._chatc                    sL   j rdj v rtd  t|jddtf fdd}| S )Nr   )Audio is not supported for chat streamingr   rG   c                  3   s    d} g }d} j jjd
dijd
ddiD ]W}tt|}t|jdkr0|jd j}n	 r5qt
 }|d u r=q|jrBd}|jpGtj}|jpLd}| |7 } i }|rat||j}|ra||d< tt|| |d|||d	V  qd S )N Fr   r   Tr   rg   roler   ri   rh   deltar   ri   rV   )r   r   r   r   r   rB   rk   r   r   r   rC   rg   r   r#   	ASSISTANTr   r>   r   r   r   )r   rg   is_functionrf   r   r   content_deltari   r   rI   r   rS   rV   rW   gen  sL   



z OpenAI._stream_chat.<locals>.gen)r   r   r   r=   ro   r   rS   r   rI   r   rV   r   rW   r     s   /zOpenAI._stream_chatc           	      K   s   |   }| jdi |}| || | jr"|jjd|dd|}n| |jjd|dd|}W d    n1 s;w   Y  |jd j}|jd j}d }|rTt	|}t
|||| |dS NF)r   r   r   )r]   r   ru   ri   rV   )r   r   _update_max_tokensr{   r   r   r   r]   ru   r5   r   r   )	rS   r   rI   r   r   rf   r]   openai_completion_logprobsru   rV   rV   rW   r   9  s:   zOpenAI._completec                    sF     jdddi|   dtf fdd}| S )Nr   TrG   c                  3   sr    d} j jddi D ](}t|jdkr$|jd j}|d u r#d}nd}| |7 } t|| ||dV  qd S Nr   r   r   )r   r]   r   ri   rV   r   r   rk   r   r]   r   r   r]   rf   r   r   r   r   rS   rV   rW   r   `  s*   


z$OpenAI._stream_complete.<locals>.genrV   )r   r   r   r!   rS   r   rI   r   rV   r   rW   r   Z  s
   zOpenAI._stream_completer   c                 C   sb   | j dus
| jdu rdS t| j|}| jj| }|dkr+td| d| jj d||d< dS )z.Infer max_tokens for the payload, if possible.Nr   zThe prompt has zO tokens, which is too long for the model. Please use a prompt that fits within z tokens.rt   )rt   r   rk   r_   r   r   r   )rS   r   r   
num_tokensrt   rV   rV   rW   r   v  s   zOpenAI._update_max_tokensraw_responsec                 C   s   t |drz|jj}|jj}|jj}W n1 ty   i  Y S w t|trC|di }|du r0i S |dd}|dd}|dd}ni S |||dS )z-Get the token usage reported by the response.usageNprompt_tokensr   completion_tokenstotal_tokens)r   r   r   )	hasattrr   r   r   r   AttributeErrorr   dictrj   )rS   r   r   r   r   r   rV   rV   rW   r     s(   

z!OpenAI._get_response_token_countsc                    4   |  |r
| j}nt| j}||fi |I d H S r^   )r   _achatr   
_acomplete)rS   r   rI   achat_fnrV   rV   rW   achat  s
   

zOpenAI.achatc                    r   r^   )r   _astream_chatr   _astream_complete)rS   r   rI   astream_chat_fnrV   rV   rW   astream_chat  s   
zOpenAI.astream_chatc                    sL   | j rd| j v rtd| |rt| j}n| j}||fi |I d H S r   )r   r   r   r   r   r   )rS   r   r   rI   acomplete_fnrV   rV   rW   	acomplete  s   
zOpenAI.acompletec                    s4   |  |rt| j}n| j}||fi |I d H S r^   )r   r   r   r   )rS   r   r   rI   astream_complete_fnrV   rV   rW   astream_complete  s   
zOpenAI.astream_completec           
   	      s
  |   }t|| jd}| jr&|jjjd|dd| jdi |I d H }n2|4 I d H ! |jjjd|dd| jdi |I d H }W d   I d H  n1 I d H sSw   Y  |jd j	}t
|| jpedgd}|jd j}d }	|rz|jrzt|j}	t|||	| |dS r   )r   r=   ro   r{   r   r   r   r   r   rh   r6   r   ru   r   r7   r   r   )
rS   r   rI   aclientr   rf   r   rh   r   ru   rV   rV   rW   r     sD   

(

zOpenAI._achatc                    sN   j rdj v rtd  t|jddtf fdd}| S )Nr   r   r   rG   c            	        s0  d} g }d}d} j jjd
dijd
ddiI d H 2 zt3 d H W }tt|}t|jdkrP|rI|jd jj	d u rI|jd jj
d u rId}q |jd j}n rUq t }d}|d u r_q |j
rdd}|jpitj}|j	pnd}| |7 } i }|rt||j
}|r||d< tt|| |d|||d	V  q 6 d S )Nr   FTr   r   r   rg   r   r   rV   )r   r   r   r   r   rB   rk   r   r   r   rg   r   rC   r   r#   r   r>   r   r   r   )	r   rg   r   first_chat_chunkrf   r   r   r   ri   r  rI   r   rS   rV   rW   r     s\   


z!OpenAI._astream_chat.<locals>.gen)r   r   r   r=   ro   r   r   rV   r  rW   r     s   :zOpenAI._astream_chatc           	   	      s   |   }| jdi |}| || | jr&|jjd|dd|I d H }n+|4 I d H  |jjd|dd|I d H }W d   I d H  n1 I d H sLw   Y  |jd j}|jd j}d }|ret	|}t
|||| |dS r   )r   r   r   r{   r   r   r   r]   ru   r5   r   r   )	rS   r   rI   r  r   rf   r]   r   ru   rV   rV   rW   r   G  s<   (zOpenAI._acompletec                    sH      jdddi| dtf fdd}| S )Nr   TrG   c                    s   d}  j jddiI d H 2 z,3 d H W }t|jdkr+|jd j}|d u r*d}nd}| |7 } t|| ||dV  q6 d S r   r   r   r  r   r   rS   rV   rW   r   p  s*   

z%OpenAI._astream_complete.<locals>.genrV   )r   r   r   r    r   rV   r	  rW   r   h  s   zOpenAI._astream_completeautotoolsrE   user_msgchat_historyverboseallow_parallel_tool_callstool_choicec                 K   s   dd |D }	|dur|}n| j }| jjr.|	D ]}
|
d dkr-||
d d< d|
d d d	< qt|tr:ttj|d
}|p=g }|rE|| ||	pId|	rOt	|ndd|S )Predict and call the tool.c                 S   s   g | ]}|j  qS rV   )r   to_openai_tool).0toolrV   rV   rW   
<listcomp>  s    z3OpenAI._prepare_chat_with_tools.<locals>.<listcomp>Ntypefunctionr   F
parametersadditionalProperties)r   r   )r   r  r  )
r   r   r9   r   rd   r   r#   r   appendr<   )rS   r  r  r  r  r  r  r   rI   
tool_specs	tool_specr   rV   rV   rW   _prepare_chat_with_tools  s*   

zOpenAI._prepare_chat_with_toolsrf   c                 K   s   |st | |S )z+Validate the response from chat_with_tools.)rl   )rS   rf   r  r  rI   rV   rV   rW   "_validate_chat_with_tools_response  s   z)OpenAI._validate_chat_with_tools_responser   error_on_no_tool_callc              	   K   s   |j jdg }t|dk r|rtdt| dg S g }|D ]7}t|tts-td|jdkr6tdzt	|j
j}W n tyI   i }Y nw |t|j|j
j|d q |S )	r  rg   rL   z)Expected at least one tool call, but got z tool calls.zInvalid tool_call objectr  z(Invalid tool type. Unsupported by OpenAI)tool_id	tool_nametool_kwargs)rh   ri   rj   rk   r   r   r   r3   r  r-   r  	argumentsr  r+   idname)rS   rf   r  rI   rg   tool_selections	tool_callargument_dictrV   rV   rW   get_tool_calls_from_response  s4   
z#OpenAI.get_tool_calls_from_response
output_cls
llm_kwargsprompt_argsc                    :   |pi }d|vr
dn|d |d< t  j||fd|i|S )Structured predict.r  requiredr+  )r   structured_predictrS   r*  r   r+  r,  r   rV   rW   r0       	zOpenAI.structured_predictc                    B   |pi }d|vrdn|d |d< t  j||fd|i|I dH S )r.  r  r/  r+  N)r   astructured_predictr1  r   rV   rW   r4       	zOpenAI.astructured_predictc                    r-  )Stream structured predict.r  r/  r+  )r   stream_structured_predictr1  r   rV   rW   r7    r2  z OpenAI.stream_structured_predictc                    r3  )r6  r  r/  r+  N)r   astream_structured_predictr1  r   rV   rW   r8    r5  z!OpenAI.astream_structured_predict)F)NNFFr
  N)Tr^   )pr`   ra   rb   rc   r$   DEFAULT_OPENAI_MODELro   rd   __annotations__r'   rr   floatrt   r   re   ru   boolrv   r   ri   r   r   rJ   ry   rz   r{   r|   r}   r~   r   r   r
   r   r	   r   r%   r   r   r   r?   r   httpxClientr   AsyncClientr1   DEFAULTr&   r   r   r   r0   r   r   r   r   r   classmethodr   propertyr\   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   r  r  r    r  r   r   r   r   r   r  r  r+   r)  
dispatcherspanr   r,   r.   r0  r4  r   r/   r7  r   r8  __classcell__rV   rV   r   rW   rA      s  
 (	


M			
#%= %H  

	


-

(rA   )drY   typingr   r   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r=  r    llama_index.core.instrumentationcoreinstrumentation
instrument(llama_index.core.base.llms.generic_utilsr   r   r   r   r   r   r   r    llama_index.core.base.llms.typesr   r   r   r   r   r    r!   r"   r#    llama_index.core.bridge.pydanticr$   r%   llama_index.core.callbacksr&   llama_index.core.constantsr'   llama_index.core.llms.callbacksr(   r)   &llama_index.core.llms.function_callingr*   llama_index.core.llms.llmr+   r,   llama_index.core.llms.utilsr-   llama_index.core.promptsr.   llama_index.core.program.utilsr/   llama_index.core.typesr0   r1   llama_index.llms.openai.utilsr2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   openair?   r@   rA   r   'openai.types.chat.chat_completion_chunkrB   rC   rD   get_dispatcherr`   rC  llama_index.core.tools.typesrE   r9  r[   r\   rl   rV   rV   rV   rW   <module>   s<    L(,
<
"