
    7|ho                       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lAZA ej                  eC      ZDddZE	 d	 	 	 	 	 ddZF	 d	 	 	 	 	 	 	 d dZG	 	 	 	 	 	 d!dZH	 	 	 	 	 	 d"dZI eddd       G d de             ZJy)#z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_v1c                 @    	 dd l } | S # t        $ r t        d      w xY w)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   s    e/var/www/html/test/engine/venv/lib/python3.12/site-packages/langchain_community/chat_models/openai.py_import_tiktokenr4   F   s4    
 O  
=
 	

s    
ChatOpenAIc                   dd l }|j                  j                  |j                  j                  |j                  j                  |j                  j
                  |j                  j                  g}t        || j                  |      S )Nr   )error_typesmax_retriesrun_manager)	openaierrorTimeoutAPIErrorAPIConnectionErrorRateLimitErrorServiceUnavailableErrorr   r8   )llmr9   r:   errorss       r3   _create_retry_decoratorrC   R   sk      	''##,,F '[     c                    K   t               r$  j                  j                  di | d{   S t         |      }|d fd       } |di | d{   S 7 ,7 w)z0Use tenacity to retry the async completion call.Nr9   c                 X   K    j                   j                  di |  d {   S 7 wN )clientacreate)kwargsrA   s    r3   _completion_with_retryz6acompletion_with_retry.<locals>._completion_with_retryq   s)      (SZZ''1&1111s    *(*rI   rL   r   returnr   )r/   async_clientcreaterC   )rA   r9   rL   retry_decoratorrM   s   `    r3   acompletion_with_retryrS   f   si      ~,S%%,,6v666-c{KO2 2 (1&111 7 2s!   *AA'AAAAc                @   | j                  d      }| j                  d      xs d}i }| j                  d      r!t        | d         }d|v r
|d   d|d<   ||d<   | j                  d      r| d   |d<   |dk(  s	|t        k(  rt        |      S |d	k(  s	|t        k(  rt        ||
      S |dk(  s	|t        k(  rt	        |      S |dk(  s	|t
        k(  rt        || d         S |dk(  s	|t        k(  rt        || d         S |s	|t        k(  rt        ||      S  ||      S )Nrolecontent function_callname
tool_callsuser)rV   	assistant)rV   additional_kwargssystemfunction)rV   rY   tooltool_call_id)rV   ra   )rV   rU   )getdictr   r   r   r   r    r   )_dictdefault_classrU   rV   r]   rX   s         r3   _convert_delta_to_message_chunkrf   y   s@    99VDii	"(bG yy!U?34]"}V'<'D$&M&!-:/*yy*/*=,'v~*;; 11		 ?gARSS		].@@!'22		}0DD#G%-HH	=,<<eN>STT	"22d;;W--rD   c                   t        |t              r8t        | t              s#t        dt        |       dt        |              || z   S t        |t              rqt        | t              s#t        dt        |       dt        |              |j                         D ci c]"  \  }}|t        | j                  |d      |      $ c}}S t        j                  dt        |              |S c c}}w )Nz%Got different types for token usage: z and r   z!Unexpected type for token usage: )

isinstanceint
ValueErrortyperc   items_update_token_usagerb   warningswarn)overall_token_usage	new_usagekvs       r3   rm   rm      s    
 )S!-s37	?#5.A)B(CE  ...	It	$-t47	?#5.A)B(CE  ")
1 "#6#:#:1a#@!DD
 	

 	9$y/9JKL
s   'C-z0.0.10z1.0zlangchain_openai.ChatOpenAI)sinceremovalalternative_importc                      e Zd ZU dZedJd       ZedKd       ZedLd       ZedMd       Z	 e
dd	
      Zded<    e
dd	
      Zded<    e
dd      Zded<   	 dZded<   	  e
e      Zded<   	  e
dd      Zded<   	  e
dd      Zded<   	  e
dd      Zded<   	 dZded<    e
dd       Zd!ed"<   	  e
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d0ed1<   dZd2ed3<   	  ed	4      Z  e!d56      edNd7              Z"e#dOd8       Z$edLd9       Z%	 dP	 	 	 	 	 dQd:Z&dRd;Z'	 	 dS	 	 	 	 	 	 	 	 	 dTd<Z(	 	 	 dU	 	 	 	 	 	 	 	 	 	 	 dVd=Z)	 	 	 	 	 	 dWd>Z*dXd?Z+	 	 dS	 	 	 	 	 	 	 	 	 dYd@Z,	 	 	 dU	 	 	 	 	 	 	 	 	 	 	 dZdAZ-edLdB       Z.edLdC       Z/	 dP	 	 	 	 	 d[ fdDZ0ed\dE       Z1d]dFZ2d^ fdGZ3	 dP	 	 	 	 	 d_ fdHZ4	 dP	 	 	 	 	 	 	 d` fdIZ5 xZ6S )ar5   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")
    c                
    ddiS )Nopenai_api_keyOPENAI_API_KEYrI   selfs    r3   
lc_secretszChatOpenAI.lc_secrets   s     "233rD   c                
    g dS )z*Get the namespace of the langchain object.)	langchainchat_modelsr:   rI   clss    r3   get_lc_namespacezChatOpenAI.get_lc_namespace   s
     65rD   Dict[str, Any]c                    i }| j                   r| j                   |d<   | j                  r| j                  |d<   | j                  r| j                  |d<   |S )Nopenai_organizationopenai_api_baseopenai_proxy)r   r   r   )r|   
attributess     r3   lc_attributeszChatOpenAI.lc_attributes   sZ    %'
##040H0HJ,-,0,@,@J())-):):J~&rD   boolc                     y)z9Return whether this model can be serialized by Langchain.TrI   r   s    r3   is_lc_serializablezChatOpenAI.is_lc_serializable   s     rD   NT)defaultexcluder   rJ   rP   gpt-3.5-turbomodel)r   aliasstr
model_namegffffff?floattemperature)default_factorymodel_kwargsapi_keyOptional[str]ry   base_urlr   organizationr   r   timeoutz,Union[float, Tuple[float, float], Any, None]request_timeout   r   ri   r8   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)populate_by_namebefore)modec           
     `   t        |       }|j                  di       }t        |      D ]M  }||v rt        d| d      ||vst        j                  d| d| d| d       |j                  |      ||<   O |j                  |j                               }|rt        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'   rb   listrj   loggerwarningpopintersectionkeys)r   valuesall_required_field_namesextra
field_nameinvalid_model_kwargss         r3   build_extrazChatOpenAI.build_extra  s     $<C#@ 

>2.v, 		;JU" 6*5E!FGG!99!* .L !))34JN
 %+JJz$:j!		;  8DDUZZ\R23 4S T 
 "'~rD   c           	        |d   dk  rt        d      |d   dkD  r|d   rt        d      t        |dd      |d<   |d   xs, t        j                  d	      xs t        j                  d
      |d<   |d   xs t        j                  d      |d<   t        |ddd      |d<   	 ddl}t               r|d   |d   |d   |d   |d   |d   |d   |d   d}|j                  d      s) |j                  di |j                  j                  |d<   |j                  d      s) |j                  di |j                  j                  |d<   |S |j                  d      s|j                  |d<   |S 	 |S # t
        $ r t        d      w xY w)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.ry   rz   r   OPENAI_ORG_IDOPENAI_ORGANIZATIONr   OPENAI_API_BASEr   OPENAI_PROXYrW   r   r   NzTCould not import openai python package. Please install it with `pip install openai`.r   r8   r   r   r   )r   r   r   r   r8   r   r   r   rJ   rP   rI   )rj   r&   osgetenvr:   r2   r/   rb   OpenAIchatcompletionsAsyncOpenAIChatCompletion)r   r   r:   client_paramss       r3   validate_environmentzChatOpenAI.validate_environment3  s    #;?455#;?vk2:;;#7$&6$
 
 () 0yy)0yy./ 	$%
 %++<$= %
B
 ! "6	"
~	 >!"23 &'< ="#45!"34%m4#)*;#<!'!8%m4	M ::h'#06==#A=#A#F#F#R#Rx ::n-););); *#*${{ ~& 	 H%%44F8  9  	? 	s   $E0 0Fc                    | j                   | j                  | j                  | j                  d| j                  }| j
                  | j
                  |d<   | j                  t               s| j                  |d<   |S )z2Get the default parameters for calling OpenAI API.)r   streamr   r   r   r   )r   r   r   r   r   r   r   r/   )r|   paramss     r3   _default_paramszChatOpenAI._default_paramsn  sy     __nn++	

 
 ??&#'??F< +LN(,(<(<F$%rD   c                     t               r  j                  j                  di |S t         |      }|d fd       } |di |S )z*Use tenacity to retry the completion call.rF   c                 <     j                   j                  di | S rH   )rJ   rQ   )rL   r|   s    r3   rM   z@ChatOpenAI.completion_with_retry.<locals>._completion_with_retry  s    %4;;%%///rD   rI   rN   )r/   rJ   rQ   rC   )r|   r9   rL   rR   rM   s   `    r3   completion_with_retryz ChatOpenAI.completion_with_retry~  sR     >%4;;%%///1$KP		0 
	0 &///rD   c                    i }d }|D ]T  }||d   }|4|j                         D ]!  \  }}||v rt        ||   |      ||<   |||<   # |D|j                  d      }V || j                  d}|r||d<   |S )Ntoken_usagesystem_fingerprint)r   r   )rl   rm   rb   r   )	r|   llm_outputsrp   r   outputr   rr   rs   combineds	            r3   _combine_llm_outputszChatOpenAI._combine_llm_outputs  s    $&!! 	FF~ /K&'--/ 3DAq//1D/2A2+A. 23+A.3 ")%+ZZ0D%E"	F $7dooV-?H)*rD   c              +    K   | j                  ||      \  }}i ||ddi}t        } | j                  d||d|D ]  }t        |t              s|j	                         }t        |d         dk(  r5|d   d   }	|	d   Ct        |	d   |      }|	j                  d      }
|
t	        |
      nd }|j                  }t        ||	      }|r|j                  |j                  |
       |  y w)Nr   Tmessagesr9   choicesr   deltafinish_reasonr   messagegeneration_info)chunkrI   )_create_message_dictsr   r   rh   rc   lenrf   rb   	__class__r"   on_llm_new_tokentextr|   r   stopr9   rL   message_dictsr   default_chunk_classr   choicer   r   cg_chunks                r3   _streamzChatOpenAI._stream  s&     !% : :8T Jv5F5f5h5,/T// 
"
?E
 	E eT*

5#$)9%a(Fg&3w!4E #JJ7M5B5N=1TX  #(//*H ,,X]](,KN/	s   C-C/c                    ||n| j                   }|r! | j                  |f||d|}t        |      S | j                  ||      \  }}	i |	|d|ini |}	 | j                  d||d|	}
| j                  |
      S )Nr   r9   r   r   rI   )r   r   r   r   r   _create_chat_resultr|   r   r   r9   r   rL   should_streamstream_iterr   r   responses              r3   	_generatezChatOpenAI._generate  s     #)"4$..&$,,#@FK (44 $ : :8T Jv

%+%7&!R
 

 .4-- 
"
?E
 ''11rD   c                    | j                   }|d|v rt        d      ||d<   |D cg c]  }t        |       }}||fS c c}w )Nr   z2`stop` found in both the input and default params.)_client_paramsrj   r.   )r|   r   r   r   mr   s         r3   r   z ChatOpenAI._create_message_dicts  s\     $$ !UVV!F6N=EF03FFf$$ Gs   ?c                ~   g }t        |t              s|j                         }|d   D ]U  }t        |d         }t        |j                  d            }d|v r|d   |d<   t	        ||      }|j                  |       W |j                  di       }|| j                  |j                  dd	      d
}t        ||      S )Nr   r   r   r   logprobsr   usager   rW   )r   r   r   )generations
llm_output)rh   rc   r-   rb   r!   appendr   r#   )	r|   r   r   resr   r   genr   r   s	            r3   r   zChatOpenAI._create_chat_result  s    (D)}}HI& 		$C-c)n=G"1IJOS .1*o
+  /C s#		$ ll7B/&//"*,,/CR"H


 kjIIrD   c                 K   | j                  ||      \  }}i ||ddi}t        }t        | f||d| d {   2 3 d {   }t        |t              s|j	                         }t        |d         dk(  r;|d   d   }	|	d   It        |	d   |      }|	j                  d      }
|
t	        |
      nd }|j                  }t        ||	      }|r%|j                  |j                  |
       d {    | 7 7 7 6 y w)Nr   Tr   r   r   r   r   r   r   )tokenr   )r   r   rS   rh   rc   r   rf   rb   r   r"   r   r   r   s                r3   _astreamzChatOpenAI._astream  sD     !% : :8T Jv5F5f5h5,!7"
(k"
EK"
 
 	 	% eT*

5#$)9%a(Fg&3w!4E #JJ7M5B5N=1TX  #(//*H !22h2WWWN/
 	, X-
sE   8DC>DDD DB,D3D4D DDDc                  K   ||n| j                   }|r) | j                  |f||d|}t        |       d {   S | j                  ||      \  }}	i |	|d|ini |}	t	        | f||d|	 d {   }
| j                  |
      S 7 O7 w)Nr   r   r   )r   r  r   r   rS   r   r   s              r3   
_ageneratezChatOpenAI._agenerate&  s      #)"4$..'$--#@FK /{;;; $ : :8T Jv

%+%7&!R
 

 0
(k
EK
 
 ''11 <
s!   7BB	9B3B4BBc                :    i d| j                   i| j                  S )zGet the identifying parameters.r   )r   r   r{   s    r3   _identifying_paramszChatOpenAI._identifying_params@  s$     K<1JT5I5IJJrD   c                   d| j                   i}t               s3|j                  | j                  | j                  | j
                  d       | j                  r"ddl}| j                  | j                  d|_        i | j                  |S )z.Get the parameters used for the openai client.r   )r   api_baser   r   N)httphttps)
r   r/   updatery   r   r   r   r:   proxyr   )r|   openai_credsr:   s      r3   r   zChatOpenAI._client_paramsE  s     T__(
 ~#22 $ 4 4$($<$< $($5$5@Q@QRFL7$&&7,77rD   c                \    d| j                   it        | 	  |      | j                  |S )z,Get the parameters used to invoke the model.r   )r   )r   super_get_invocation_paramsr   )r|   r   rL   r   s      r3   r  z!ChatOpenAI._get_invocation_paramsY  sG    
 T__
g,$,7
 ""
 	
 	
rD   c                     y)zReturn type of chat model.zopenai-chatrI   r{   s    r3   	_llm_typezChatOpenAI._llm_typed  s     rD   c                   t               }| j                  | j                  }n| j                  }|dk(  rd}n|dk(  rd}	 |j                  |      }||fS # t        $ r. t
        j                  d       d}|j                  |      }Y ||fS w xY w)Nr   gpt-3.5-turbo-0301gpt-4z
gpt-4-0314z5Warning: model not found. Using cl100k_base encoding.cl100k_base)r4   r   r   encoding_for_modelKeyErrorr   r   get_encoding)r|   	tiktoken_r   encodings       r3   _get_encoding_modelzChatOpenAI._get_encoding_modeli  s    $&	##/,,EOOE' -'! %	5 33E:H
 h	  	5NNRS!E --e4Hh		5s    A 1BBc                    t         j                  d   dk  rt        |   |      S | j	                         \  }}|j                  |      S )z9Get the tokens present in the text with tiktoken package.r      )sysversion_infor  get_token_idsr  encode)r|   r   _encoding_modelr   s       r3   r   zChatOpenAI.get_token_ids  sL     A!#7(.. 446>$$T**rD   c           
     0   |t        j                  d       t        j                  d   dk  rt        |   |      S | j                         \  }}|j                  d      rd}d}n6|j                  d      s|j                  d      rd	}d}nt        d
| d      d}|D cg c]  }t        |       }	}|	D ]P  }
||z  }|
j                         D ]6  \  }}|t        |j                  t        |                  z  }|dk(  s2||z  }8 R |d	z  }|S c c}w )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.ipynbzECounting 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   rY   )rn   ro   r  r  r  get_num_tokens_from_messagesr  
startswithNotImplementedErrorr.   rl   r   r!  r   )r|   r   toolsr   r  tokens_per_messagetokens_per_name
num_tokensr   messages_dictr   keyvaluer   s                r3   r(  z'ChatOpenAI.get_num_tokens_from_messages  sM    MMW A!#77AA224x01!" Oo.%2B2B72K!"O%"G $GG  
=EF03FF$ 	2G,,J%mmo 2
U c(//#e*"=>>
&=/1J2	2 	a
 Gs   #Dc                    ddl m} |D cg c]
  } ||       }}|Ht        |      dk7  rt        d      |d   d   |k7  rt        d| d|d   d    d      d|i}i |d	|i}t	        |   dd
|i|S c c}w )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_functionr   zGWhen specifying `function_call`, you must provide exactly one function.rY   zFunction call z3 was specified, but the only provided function was .rX   	functionsrI   )&langchain.chains.openai_functions.baser3  r   rj   r  bind)	r|   r5  rX   rL   r3  fnformatted_functionsfunction_call_r   s	           r3   bind_functionszChatOpenAI.bind_functions  s    ( 	VHQR"9"=RR$&'1,    #1%f-> $]O 4--@-CF-K,LAO  %m4N@@@Fw| 
)

 	
 Ss   A8)rO   zDict[str, str])rO   z	List[str])rO   r   )rO   r   )r   r   rO   r   )r   r   rO   r   N)r9   "Optional[CallbackManagerForLLMRun]rL   r   rO   r   )r   zList[Optional[dict]]rO   rc   )NN)
r   List[BaseMessage]r   Optional[List[str]]r9   r=  rL   r   rO   zIterator[ChatGenerationChunk])NNN)r   r>  r   r?  r9   r=  r   Optional[bool]rL   r   rO   r#   )r   r>  r   r?  rO   z+Tuple[List[Dict[str, Any]], Dict[str, Any]])r   zUnion[dict, BaseModel]rO   r#   )
r   r>  r   r?  r9   'Optional[AsyncCallbackManagerForLLMRun]rL   r   rO   z"AsyncIterator[ChatGenerationChunk])r   r>  r   r?  r9   rA  r   r@  rL   r   rO   r#   )r   r?  rL   r   rO   r   )rO   r   )rO   zTuple[str, tiktoken.Encoding])r   r   rO   z	List[int])r   r>  r+  zCOptional[Sequence[Union[Dict[str, Any], Type, Callable, BaseTool]]]rO   ri   )r5  z:Sequence[Union[Dict[str, Any], Type[BaseModel], Callable]]rX   r   rL   r   rO   z)Runnable[LanguageModelInput, BaseMessage])7__name__
__module____qualname____doc__propertyr}   classmethodr   r   r   r+   rJ   __annotations__rP   r   r   rc   r   ry   r   r   r   r   r8   r   r   r   r   r   r   r   r*   model_configr,   r   r(   r   r   r   r   r   r   r   r   r  r  r  r   r  r  r  r   r(  r;  __classcell__)r   s   @r3   r5   r5      s    4 4 6 6     d3FC3dD9L#9O7CJCK+#(#>L.>V %*$i$HNMHO%*4z%JO]J).t>)RRN"&L-&DIIEOA Q'K'<It/AsJA $J$/)--J 7;O3:7;M4; %)K!( L (#  $2 8 8t    AE0=0PS0	04 %):>	"#" "" 8	"
 " 
'"N %):>!%2#2 "2 8	2
 2 2 
22	%)	%1D	%	4	%J2 %)?C	"#" "" =	"
 " 
,"N %)?C!%2#2 "2 =	2
 2 2 
24 K K 8 8( +/	
'	
:=	
		
  .+ -#-
- 
-d (,'
M'
 %'
 	'

 
3'
 '
rD   )rO   r   r<  )rA   r5   r9   zHOptional[Union[AsyncCallbackManagerForLLMRun, CallbackManagerForLLMRun]]rO   zCallable[[Any], Any])rA   r5   r9   rA  rL   r   rO   r   )rd   zMapping[str, Any]re   zType[BaseMessageChunk]rO   r   )rp   Union[int, dict]rq   rK  rO   rK  )KrE  
__future__r   loggingr   r  rn   typingr   r   r   r   r   r	   r
   r   r   r   r   r   r   langchain_core._api.deprecationr   langchain_core.callbacksr   r   langchain_core.language_modelsr   *langchain_core.language_models.chat_modelsr   r   r   #langchain_core.language_models.llmsr   langchain_core.messagesr   r   r   r   r   r   r   r    langchain_core.outputsr!   r"   r#   langchain_core.runnablesr$   langchain_core.toolsr%   langchain_core.utilsr&   r'   r(   pydanticr)   r*   r+   r,   #langchain_community.adapters.openair-   r.    langchain_community.utils.openair/   r1   	getLoggerrB  r   r4   rC   rS   rf   rm   r5   rI   rD   r3   <module>r]     s^    "  	 
      7 > 
 L	 	 	 S R - ) 
 C B : 
		8	$	  			
 , <@2	282 2 		2&..-C..<)6F6 
E6Si
 i
i
rD   