
    dhY                        S SK r S SKrS SKrS SKrS SKrS SKrS SKrS SKJr  S SKJr  S SK	J
r
  S SKJrJrJrJrJrJrJrJrJr  S SKJrJrJr  S SKJr  S SKJr  S S	KJrJr  S S
K J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(J)r)J*r*J+r+  S SK,J-r-J.r.  S SK/J0r0J1r1J2r2  S SK3J4r4J5r5  S SK6J7r7  S SK8J9r9J:r:J;r;  \Rx                  " \=5      r>Sr?Sr@S\#S\A4S jrBS\\C\4   S\#4S jrDS\\C\4   S\\$   S\$4S jrE " S S\5      rF " S S5      rGg)    N)datetime)Queue)mktime)	AnyDict	GeneratorIteratorListMappingOptionalTypecast)	urlencodeurlparse
urlunparse)format_date_time)CallbackManagerForLLMRun)BaseChatModelgenerate_from_stream)	AIMessageAIMessageChunkBaseMessageBaseMessageChunkChatMessageChatMessageChunkFunctionMessageChunkHumanMessageHumanMessageChunkSystemMessageToolMessageChunk)make_invalid_tool_callparse_tool_call)ChatGenerationChatGenerationChunk
ChatResult)get_from_dict_or_envget_pydantic_field_names)
get_fields)
ConfigDictFieldmodel_validatorz$wss://spark-api.xf-yun.com/v3.5/chatzgeneralv3.5messagereturnc                    [        U [        5      (       a  SU R                  S.nU$ [        U [        5      (       a  SU R                  S.nU$ [        U [        5      (       aq  SU R                  S.nSU R
                  ;   a   U R
                  S   US'   US   S:X  a  S US'   SU R
                  ;   a   U R
                  S   US'   US   S:X  a  S US'   U$ [        U [        5      (       a  SU R                  S.nU$ [        S	U  35      e)
Nuser)rolecontent	assistantfunction_callr1    
tool_callssystemzGot unknown type )
isinstancer   r1   r   r   additional_kwargsr   
ValueError)r,   message_dicts     `/var/www/html/shao/venv/lib/python3.13/site-packages/langchain_community/chat_models/sparkllm.pyconvert_message_to_dictr<   9   s   ';'' &7??C( ' 
G\	*	* &7??C$ # 
GY	'	' +Hg777,3,E,Eo,VL)I&",*.Y'7444)0)B)B<)PL&I&",*.Y'  
G]	+	+ (W__E  ,WI677    _dictc           
         U S   nU S   nUS:X  a	  [        US9$ US:X  a  / n0 nU R                  S5      =n(       a  [        U5      US'   / nU R                  S5      =n(       a+  XtS'   U S    H  n UR                  [	        USS	95        M     O0 nU=(       d    S
n
[        U
UUUS9$ US:X  a	  [        US9$ [        X!S9$ ! [
         a/  n	UR                  [        U[        U	5      5      5         S n	A	M  S n	A	ff = f)Nr0   r1   r/   r1   r2   r3   r5   T)	return_idr4   )r1   r8   r5   invalid_tool_callsr6   r1   r0   )r   getdictappendr"   	Exceptionr!   strr   r   r   )r>   msg_rolemsg_contentrB   r8   r3   r5   raw_tool_callsraw_tool_caller1   s              r;   convert_dict_to_messagerN   S   s(   V}H	"K6K00	[	 "$!IIo66=615m1Do.
"YY|44>4.<l+!&|!4%%omt&TU "5 !##/!1	
 	
 
X	[11;>>! ! &--.}c!fE s   1C  
C9
$C44C9default_classc                 V   [        [        U R                  S5      5      n[        [        U R                  S5      =(       d    S5      n0 nU R                  S5      (       a#  [        U S   5      nSU;   a  US   c  SUS'   XTS'   U R                  S5      (       a  U S   US'   US:X  d
  U[        :X  a	  [	        US9$ US	:X  d
  U[
        :X  a	  [        X4S
9$ US:X  d
  U[        :X  a  [        X0S   S9$ US:X  d
  U[        :X  a  [        X0S   S9$ U(       d
  U[        :X  a	  [        X2S9$ U" US9$ )Nr0   r1   r4   r3   namer5   r/   r@   r2   )r1   r8   function)r1   rQ   tooltool_call_id)r1   rT   rC   )	r   rH   rD   rE   r   r   r   r    r   )r>   rO   rI   rJ   r8   r3   s         r;   _convert_delta_to_message_chunkrU   v   s/    C6*+HsEIIi06B7K yy!!U?34]"}V'<'D$&M&!-:/*yy*/*=,'6].?? 55	[	 M^$CkWW	Z	=4H#H#KFmLL	V	}0@@BWXX	]&66CC[11r=   c                      \ rS rSr% Sr\S\4S j5       r\S\	\
\
4   4S j5       rSr\\S'   \" SSS	9r\\
   \S
'    \" SSS	9r\\
   \S'    \" SSS	9r\\
   \S'    \" SSS	9r\\
   \S'    \" SSS	9r\\
   \S'    Sr\
\S'   Sr\\S'    \" SSS9r\\S'    \" SS9r\\S'    Sr\\S'    \" \S 9r\	\
\4   \S!'    \" S"S#9r \!" S$S%9\S&\	S\4S' j5       5       r"\!" S$S%9\S&\	\
\4   S\4S( j5       5       r#  S2S)\$\%   S*\\$\
      S+\\&   S,\S\'\(   4
S- jjr)   S3S)\$\%   S*\\$\
      S+\\&   S.\\   S,\S\*4S/ jjr+\S\
4S0 j5       r,S1r-g)4ChatSparkLLM   u  IFlyTek Spark chat model integration.

Setup:
    To use, you should have the environment variable``IFLYTEK_SPARK_API_KEY``,
    ``IFLYTEK_SPARK_API_SECRET`` and ``IFLYTEK_SPARK_APP_ID``.

Key init args — completion params:
    model: Optional[str]
        Name of IFLYTEK SPARK model to use.
    temperature: Optional[float]
        Sampling temperature.
    top_k: Optional[float]
        What search sampling control to use.
    streaming: Optional[bool]
         Whether to stream the results or not.

Key init args — client params:
    api_key: Optional[str]
        IFLYTEK SPARK API KEY. If not passed in will be read from env var IFLYTEK_SPARK_API_KEY.
    api_secret: Optional[str]
        IFLYTEK SPARK API SECRET. If not passed in will be read from env var IFLYTEK_SPARK_API_SECRET.
    api_url: Optional[str]
        Base URL for API requests.
    timeout: Optional[int]
        Timeout for requests.

See full list of supported init args and their descriptions in the params section.

Instantiate:
    .. code-block:: python

        from langchain_community.chat_models import ChatSparkLLM

        chat = ChatSparkLLM(
            api_key="your-api-key",
            api_secret="your-api-secret",
            model='Spark4.0 Ultra',
            # temperature=...,
            # other params...
        )

Invoke:
    .. code-block:: python

        messages = [
            ("system", "你是一名专业的翻译家，可以将用户的中文翻译为英文。"),
            ("human", "我喜欢编程。"),
        ]
        chat.invoke(messages)

    .. code-block:: python

        AIMessage(
            content='I like programming.',
            response_metadata={
                'token_usage': {
                    'question_tokens': 3,
                    'prompt_tokens': 16,
                    'completion_tokens': 4,
                    'total_tokens': 20
                }
            },
            id='run-af8b3531-7bf7-47f0-bfe8-9262cb2a9d47-0'
        )

Stream:
    .. code-block:: python

        for chunk in chat.stream(messages):
            print(chunk)

    .. code-block:: python

        content='I' id='run-fdbb57c2-2d32-4516-b894-6c5a67605d83'
        content=' like programming' id='run-fdbb57c2-2d32-4516-b894-6c5a67605d83'
        content='.' id='run-fdbb57c2-2d32-4516-b894-6c5a67605d83'

    .. code-block:: python

        stream = chat.stream(messages)
        full = next(stream)
        for chunk in stream:
            full += chunk
        full

    .. code-block:: python

        AIMessageChunk(
            content='I like programming.',
            id='run-aca2fa82-c2e4-4835-b7e2-865ddd3c46cb'
        )

Response metadata
    .. code-block:: python

        ai_msg = chat.invoke(messages)
        ai_msg.response_metadata

    .. code-block:: python

        {
            'token_usage': {
                'question_tokens': 3,
                'prompt_tokens': 16,
                'completion_tokens': 4,
                'total_tokens': 20
            }
        }

r-   c                     g)z9Return whether this model can be serialized by Langchain.F )clss    r;   is_lc_serializableChatSparkLLM.is_lc_serializable  s     r=   c                     SSSSSS.$ )NIFLYTEK_SPARK_APP_IDIFLYTEK_SPARK_API_KEYIFLYTEK_SPARK_API_SECRETIFLYTEK_SPARK_API_URLIFLYTEK_SPARK_LLM_DOMAIN)spark_app_idspark_api_keyspark_api_secretspark_api_urlspark_llm_domainrZ   selfs    r;   
lc_secretsChatSparkLLM.lc_secrets  s     34 :4 :
 	
r=   Nclientapp_id)defaultaliasrd   api_keyre   
api_secretrf   api_urlrg   modelrh   lc_userspark_user_idF	streaming   timeout)rp   request_timeoutg      ?)ro   temperature   top_k)default_factorymodel_kwargsT)populate_by_namebefore)modevaluesc           	         [        USS/S5      US'   [        USS/S5      US'   [        USS/S	5      US'   [        US
S[        5      US
'   [        USS[        5      US'   [        U 5      R	                  5        VVs0 sH   u  p#UR
                  c  M  X#R
                  _M"     nnnUR                  S5      US   S'   UR                  S5      US   S'   [        US   US   US   US
   US   US   S9US'   U$ s  snnf )Nrd   rn   r_   re   rq   r`   rf   rr   ra   rg   rb   rh   rc   r{   r   r}   )rn   rq   rr   rs   spark_domainr   rm   )r&   SPARK_API_URLSPARK_LLM_DOMAINr(   itemsro   rD   _SparkLLMClient)r[   r   rQ   fielddefault_valuess        r;   validate_environment!ChatSparkLLM.validate_environment/  s_    "6X&""
~
 #7i(##

 &:.&&
!"
 #7#	#
 &:&	&
!"  *#446
6}}  D--6 	 

 1?0B0B=0Q~}-*8*<*<W*E~w'*.)?+01?+ 23/
x !
s   =C9C9c           
      p   [        U 5      nUR                  S0 5      n[        U5       HP  nXC;   a  [        SU S35      eXB;  d  M  [        R                  SU SU SU S35        UR                  U5      X4'   MR     UR                  UR                  5       5      nU(       a  [        SU S	35      eX1S'   U$ )
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'   rD   listr9   loggerwarningpopintersectionkeys)r[   r   all_required_field_namesextra
field_nameinvalid_model_kwargss         r;   build_extraChatSparkLLM.build_extrae  s     $<C#@ 

>2.v,J" 6*5E!FGG9!* .L !))34JN
 %+JJz$:! '  8DDUZZ\R23 4S T 
 "'~r=   messagesstoprun_managerkwargsc              +     #    [         nU R                  R                  U Vs/ sH  n[        U5      PM     snU R                  U R
                  SS9  U R                  R                  U R                  S9 HR  nSU;  a  M  US   n[        X5      n	[        U	S9n
U(       a#  UR                  [        U	R                  5      U
S9  U
v   MT     g s  snf 7f)NT)rw   ry   datar,   )chunk)r   rm   arunr<   rv   r   	subscriberz   rU   r$   on_llm_new_tokenrH   r1   )rj   r   r   r   r   default_chunk_classmr1   deltar   cg_chunks              r;   _streamChatSparkLLM._stream  s      -19:A$Q':	 	 	
 {{,,T5I5I,JGW$FOE3EOE*59H,,S-?x,PN K ;s    CCBCstreamc                    U(       d  U R                   (       a   U R                  " S	XUS.UD6n[        U5      $ U R                  R	                  U Vs/ sH  n[        U5      PM     snU R                  U R                  S5        0 n0 n	U R                  R                  U R                  S9 H  n
SU
;   a  U
S   U	S'   SU
;  a  M  U
S   nM      [        U5      n[        US9/n[        XS9$ s  snf )
N)r   r   r   Fr   usagetoken_usager   r   )generations
llm_outputrZ   )rw   r   r   rm   r   r<   rv   r   r   rz   rN   r#   r%   )rj   r   r   r   r   r   stream_iterr   
completionr   r1   r,   r   s                r;   	_generateChatSparkLLM._generate  s     T^^,, !+IOK (4419:A$Q':		
 

{{,,T5I5I,JG'!,3G,<
=)W$ J K **5%g67kII ;s   C+c                     g)Nzspark-llm-chatrZ   ri   s    r;   	_llm_typeChatSparkLLM._llm_type  s    r=   rZ   )NNNNN).__name__
__module____qualname____firstlineno____doc__classmethodboolr\   propertyr   rH   rk   rm   r   __annotations__r*   rd   r   re   rf   rg   rh   rv   rw   rz   intr{   floatr}   rE   r   r)   model_configr+   r   r   r
   r   r   r	   r$   r   r%   r   r   __static_attributes__rZ   r=   r;   rW   rW      s   m^ 4   
DcN 
 
 FC"'H"EL(3-E#(Y#GM8C=G&+D&MhsmM#(Y#GM8C=G&+D&HhsmH"M3"It/ 95OS50s+K++E3N.#(#>L$sCx.>QL (#.$ .3 .  $.h (#c3h C   $: %):>	{# tCy! 67	
  
%	&8 %):>!%J{#J tCy!J 67	J
 J J 
J@  3    r=   rW   c                      \ rS rSrSr   SS\S\S\S\\   S\\   S	\\   4S
 jjr\	S\S\S\S\4S j5       r
  S S\\   S\S	\\   S\SS4
S jjr  S S\\   S\S	\\   S\S\R                   4
S jjrS\S\\   SS4S jrS\S\S\SS4S jrS\SS4S jrS\S\SS4S jr S!S\S\S	\\   S\4S jjrS"S\\   S\\SS4   4S jjrSrg)#r   i  z
Use websocket-client to call the SparkLLM interface provided by Xfyun,
which is the iFlyTek's open platform for AI capabilities
Nrn   rq   rr   rs   r   r   c                      SS K nXpl        U(       d  [        OUU l        Xl        X`l        U=(       d    [        U l        [        5       U l
        SSS.U l        X l        X0l        g ! [         a    [        S5      ef = f)Nr   zhCould not import websocket client python package. Please install it with `pip install websocket-client`.r4   r2   rC   )	websocketwebsocket_clientImportErrorr   rs   rn   r   r   r   r   queueblocking_messagerq   rr   )rj   rn   rq   rr   rs   r   r   r   s           r;   __init___SparkLLMClient.__init__  sz    	$-! -4}((<,<"''
,. D$  	I 	s   
A& &A<r-   c                    [        [        [        R                  " 5       R	                  5       5      5      n[        U 5      nUR                  nUR                  nSU SU SU S3n[        R                  " UR                  S5      UR                  S5      [        R                  S9R                  5       n[        R                  " U5      R!                  SS9n	SU S	U	 S
3n
[        R                  " U
R                  S5      5      R!                  SS9nXUS.n[#        U5      n[%        UR&                  UR                  UR                  UR(                  UUR*                  45      nU$ )z;
Generate a request url with an api key and an api secret.
zhost: z
date: z
GET z	 HTTP/1.1zutf-8)	digestmod)encodingz	api_key="zQ", algorithm="hmac-sha256",         headers="host date request-line", signature="")authorizationdatehost)r   r   r   now	timetupler   netlocpathhmacnewencodehashlibsha256digestbase64	b64encodedecoder   r   schemeparamsfragment)rs   rq   rr   r   
parsed_urlr   r   signature_originsignature_shasignature_sha_base64authorization_originr   params_dictencoded_paramsurls                  r;   _create_url_SparkLLMClient._create_url  sd     x||~'?'?'A BC g&
  #D6$vdV9M g&##G,nn
 &(	 	  &//>EEwEW!*7) 466J5K1 N(()=)D)DW)MNUU V 

 )6TR";/!!!!!!##	
 
r=   r   user_idrw   c                    U R                   R                  S5        U R                   R                  [        R	                  U R
                  U R                  U R                  5      U R                  U R                  U R                  U R                  S9nXl        X%l        Uc  U R                  OUUl        XEl        UR!                  5         g )NF)
on_messageon_erroron_closeon_open)r   enableTraceWebSocketAppr   r   rs   rq   rr   r   r   r   r   r   r   r   rw   run_forever)rj   r   r   r   rw   wss         r;   run_SparkLLMClient.run  s     	))%0""//''
 ]]]]LL 0 

 
/;/C$++ 
r=   c                 l    [         R                  " U R                  UUUU4S9nUR                  5         U$ )N)targetargs)	threadingThreadr   start)rj   r   r   r   rw   	ws_threads         r;   r   _SparkLLMClient.arun'  s>     $$88	
	 	r=   r   errorc                 ^    U R                   R                  SU05        UR                  5         g )Nr  )r   putclose)rj   r   r  s      r;   r   _SparkLLMClient.on_error:  s     

'(

r=   close_status_codeclose_reasonc                 r    [         R                  SUUS.05        U R                  R                  SS05        g )Nlog)r  r  doneT)r   debugr   r  )rj   r   r  r  s       r;   r   _SparkLLMClient.on_close>  s7    ):$0	
 	

~&r=   c                     SSS.U l         [        R                  " U R                  UR                  UR
                  UR                  S95      nUR                  U5        g )Nr4   r2   rC   )r   r   r   )r   jsondumps
gen_paramsr   r   r   send)rj   r   r   s      r;   r   _SparkLLMClient.on_openI  sN    ,. DzzOObjjr  

 	r=   r,   c                    [         R                  " U5      nUS   S   nUS:w  a:  U R                  R                  SSU SUS   S    305        UR	                  5         g US   S	   nUS
   nUS   S   S   nUR
                  (       a$  U R                  R                  SUS   S   05        OU R                  S==   U-  ss'   US:X  a  UR
                  (       d'  U R                  R                  SU R                  05        U(       a2  UR                  S0 5      R                  S0 5      R                  S0 5      O0 nU R                  R                  SU05        UR	                  5         g g )Nheadercoder   r  zCode: z	, Error: r,   payloadchoicesstatustextr1   r      r   )r  loadsr   r  r	  rw   r   rD   )	rj   r   r,   r   r  r  r  r1   
usage_datas	            r;   r   _SparkLLMClient.on_messageR  sJ   zz'"H~f%19JJNNF4&	$x.2K1LMN HHJ9oi0GX&Ffoa(3G||

(:;<%%i0G;0{||JJNNFD,A,A#BC  HHY+//<@@L 
 

45
 r=   c                     U R                   US.SSU R                  00SSU00S.nU(       a  US   S   R                  U5        [        R	                  SU 35        U$ )	N)rn   uidchatdomainr,   r  )r  	parameterr  r'  zSpark Request Parameters: )rn   r   updater   r  )rj   r   r   r   r   s        r;   r  _SparkLLMClient.gen_paramsm  sm     "&W= 8T->->"?@!FH#56
 f%,,\:1$89r=   ry   c              #      #      U R                   R                  US9nSU;   a  [	        US   5      eSU;   a  Uv   M;  SU;   a  g SU;  a  g Uv   MN  ! [         R                   a  n[        SU S35      eS nAff = f7f)Nr   z-SparkLLMClient wait LLM api response timeout z secondsr  r   r  r   )r   rD   EmptyTimeoutErrorConnectionError)rj   ry   r1   _s       r;   r   _SparkLLMClient.subscribe{  s     **...9
 '!%gg&677'! W$M!  ;; "CG9HU s'   A=A 4A=A:&A55A::A=)	rq   rr   rs   rn   r   r   r   r   r   r   )NF)N)rx   )r   r   r   r   r   rH   r   rE   r   staticmethodr   r
   r   r   r   r  r  r   r   r   r   r   r   r   r   r  r   r   r   rZ   r=   r;   r   r     s    "&&*'+%% % 	%
 #% sm% tn%8 *S *3 *C *C * *` (,t*  tn	
  
: (,t*  tn	
  
		&3 x}  	'3 	'3 	'c 	'd 	'# $ S 3 4 8 LP'*:B4.	# 	$dBR8S  r=   r   )Hr   r   r   r  loggingr   r  r   r   timer   typingr   r   r   r	   r
   r   r   r   r   urllib.parser   r   r   wsgiref.handlersr   langchain_core.callbacksr   *langchain_core.language_models.chat_modelsr   r   langchain_core.messagesr   r   r   r   r   r   r   r   r   r   r    *langchain_core.output_parsers.openai_toolsr!   r"   langchain_core.outputsr#   r$   r%   langchain_core.utilsr&   r'   langchain_core.utils.pydanticr(   pydanticr)   r*   r+   	getLoggerr   r   r   r   rE   r<   rH   rN   rU   rW   r   rZ   r=   r;   <module>r?     s             V V V 8 8 -    
 5 7 7			8	$6  [ T 4 ?738#4  ?  ?F2382-12B-C226k = k \	M Mr=   