
    dho>                    :   S SK J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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  S SKJrJrJr  S SKJr  S S	KJr  S S
KJr  S SKJr  S SK J!r!J"r"  S SK#J$r$  \RJ                  " \&5      r' " S S\5      r( " S S5      r)g)    )annotationsN)datetime)Queue)mktime)AnyDict	GeneratorIteratorListOptional)	urlencodeurlparse
urlunparse)format_date_time)CallbackManagerForLLMRun)LLM)GenerationChunk)get_from_dict_or_envpre_init)Fieldc                     \ rS rSr% SrSrS\S'   \" SSS9rS\S	'    \" SS
S9r	S\S'    \" SSS9r
S\S'    \" SSS9rS\S'    \" SSS9rS\S'    SrS\S'   SrS\S'    \" SSS9rS\S'    SrS\S'    SrS\S '    \" \S!9rS"\S#'    \S*S$ j5       r\S+S% j5       r\S,S& j5       r  S-         S.S' jjr  S-         S/S( jjrS)rg)0SparkLLM   u\
  iFlyTek Spark completion model integration.

Setup:
    To use, you should set environment variables ``IFLYTEK_SPARK_APP_ID``,
    ``IFLYTEK_SPARK_API_KEY`` and ``IFLYTEK_SPARK_API_SECRET``.

.. code-block:: bash

        export IFLYTEK_SPARK_APP_ID="your-app-id"
        export IFLYTEK_SPARK_API_KEY="your-api-key"
        export IFLYTEK_SPARK_API_SECRET="your-api-secret"

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:
    app_id: Optional[str]
        IFLYTEK SPARK API KEY. Automatically inferred from env var `IFLYTEK_SPARK_APP_ID` if not provided.
    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.llms import SparkLLM

        llm = SparkLLM(
            app_id="your-app-id",
            api_key="your-api_key",
            api_secret="your-api-secret",
            # model='Spark4.0 Ultra',
            # temperature=...,
            # other params...
        )

Invoke:
    .. code-block:: python

        input_text = "用50个字左右阐述，生命的意义在于"
        llm.invoke(input_text)

    .. code-block:: python

        '生命的意义在于实现自我价值，追求内心的平静与快乐，同时为他人和社会带来正面影响。'

Stream:
    .. code-block:: python

        for chunk in llm.stream(input_text):
            print(chunk)

    .. code-block:: python

        生命 | 的意义在于 | 不断探索和 | 实现个人潜能，通过 | 学习 | 、成长和对社会 | 的贡献，追求内心的满足和幸福。

Async:
    .. code-block:: python

        await llm.ainvoke(input_text)

        # stream:
        # async for chunk in llm.astream(input_text):
        #    print(chunk)

        # batch:
        # await llm.abatch([input_text])

    .. code-block:: python

        '生命的意义在于实现自我价值，追求内心的平静与快乐，同时为他人和社会带来正面影响。'

Nr   clientapp_id)defaultaliasOptional[str]spark_app_idapi_keyspark_api_key
api_secretspark_api_secretapi_urlspark_api_urlmodelspark_llm_domainlc_userstrspark_user_idFbool	streaming   timeoutintrequest_timeoutg      ?floattemperature   top_k)default_factoryDict[str, Any]model_kwargsc           	     |   [        USS/S5      US'   [        USS/S5      US'   [        USS/S	5      US'   [        US
S/SS5      US
'   [        USS/SS5      US'   US   =(       d    U R                  US   S'   US   =(       d    U R                  US   S'   [        US   US   US   US
   US   US   S9US'   U$ )Nr   r   IFLYTEK_SPARK_APP_IDr!   r    IFLYTEK_SPARK_API_KEYr#   r"   IFLYTEK_SPARK_API_SECRETr%   r$   IFLYTEK_SPARK_API_URL$wss://spark-api.xf-yun.com/v3.5/chatr'   r&   IFLYTEK_SPARK_LLM_DOMAINgeneralv3.5r2   r7   r4   )r   r    r"   r$   spark_domainr7   r   )r   r2   r4   _SparkLLMClient)clsvaluess     Y/var/www/html/shao/venv/lib/python3.13/site-packages/langchain_community/llms/sparkllm.pyvalidate_environmentSparkLLM.validate_environment   s&   !5X&""
~
 #7i(##

 &:.&&
!"
 #7i(#2	#
 &:)&	&
!" 17}0E0X~}-*0/*FSYY~w'*.)?+01?+ 23/
x     c                    g)zReturn type of llm.zspark-llm-chat )selfs    rD   	_llm_typeSparkLLM._llm_type   s      rG   c                    U R                   U R                  U R                  U R                  U R                  S.n0 UEU R
                  E$ )z4Get the default parameters for calling SparkLLM API.)r'   streamr0   r4   r2   )r'   r,   r0   r4   r2   r7   )rJ   normal_paramss     rD   _default_paramsSparkLLM._default_params   sL     !% 5 5nn#33ZZ++
 6-54#4#455rG   c                z   U R                   (       a-  SnU R                  " XU40 UD6 H  nXVR                  -  nM     U$ SnU R                  R	                  SUS./U R
                  U R                  U R                   5        U R                  R                  U R                  S9 H  nSU;  a  M  US   S   nM     U$ )a.  Call out to an sparkllm for each generation with a prompt.
Args:
    prompt: The prompt to pass into the model.
    stop: Optional list of stop words to use when generating.
Returns:
    The string generated by the llm.

Example:
    .. code-block:: python
        response = client("Tell me a joke.")
 userrolecontentr.   datarW   )	r,   _streamtextr   arunr*   r7   	subscriber0   )rJ   promptstoprun_managerkwargs
completionchunkrW   s           rD   _callSparkLLM._call   s    $ >>JfKJ6Jjj(
 K
01NN		
 {{,,T5I5I,JGW$ 3J K
 rG   c              +  2  #    U R                   R                  SUS./U R                  U R                  S5        U R                   R	                  U R
                  S9 H6  nSU;  a  M  US   nU(       a  UR                  U5        [        US   S9v   M8     g 7f)NrT   rU   TrX   rY   rW   )r[   )r   runr*   r7   r]   r0   on_llm_new_tokenr   )rJ   r^   r_   r`   ra   rW   deltas          rD   rZ   SparkLLM._stream   s      	01		
 {{,,T5I5I,JGW$FOE,,U3!uY'788 Ks   BBrI   )rC   r   returnr   )rk   r)   )rk   r6   )NN)
r^   r)   r_   Optional[List[str]]r`   "Optional[CallbackManagerForLLMRun]ra   r   rk   r)   )
r^   r)   r_   rl   r`   rm   ra   r   rk   zIterator[GenerationChunk])__name__
__module____qualname____firstlineno____doc__r   __annotations__r   r   r!   r#   r%   r'   r*   r,   r0   r2   r4   dictr7   r   rE   propertyrK   rP   rd   rZ   __static_attributes__rI   rG   rD   r   r      s   Vp FC"'H"EL-E#(Y#GM=G*&+D&MmM-#(Y#GM=G&+D&HmH"M3"It/ 9=OS=0K+E3N.#(#>L.>Q( (T     
6 
6 %):>	## "# 8	#
 # 
#P %):>	99 "9 8	9
 9 
#9 9rG   r   c                      \ rS rSrSr   S           SS jjr\SS j5       r  S         SS jjr  S         SS jjr	SS jr
SS	 jrSS
 jrSS jr S       SS jjrSSS jjrSrg)rA   i  z
Use websocket-client to call the SparkLLM interface provided by Xfyun,
which is the iFlyTek's open platform for AI capabilities
Nc                     SS K nXpl        U(       d  SOUU l        Xl        X`l        U=(       d    S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`.r=   r?   rS   	assistantrW   rV   )	websocketwebsocket_clientImportErrorr$   r   r7   r@   r   queueblocking_messager    r"   )rJ   r   r    r"   r$   r@   r7   r{   s           rD   __init___SparkLLMClient.__init__  s    	$-! ;B2w 	 ((9M"''
,. D$  	I 	s   
A A4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)r$   r    r"   r   
parsed_urlr   r   signature_originsignature_shasignature_sha_base64authorization_originr   params_dictencoded_paramsurls                  rD   _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";/!!!!!!##	
 
rG   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WebSocketApprA   r   r$   r    r"   r   r   r   r   messagesuser_idr7   r,   run_forever)rJ   r   r   r7   r,   wss         rD   rg   _SparkLLMClient.runW  s     	))%0""//''
 ]]]]LL 0 

 
/;/C$++ 
rG   c                l    [         R                  " U R                  UUUU4S9nUR                  5         U$ )N)targetargs)	threadingThreadrg   start)rJ   r   r   r7   r,   	ws_threads         rD   r\   _SparkLLMClient.arunp  s>     $$88	
	 	rG   c                ^    U R                   R                  SU05        UR                  5         g )Nerror)r~   putclose)rJ   r   r   s      rD   r   _SparkLLMClient.on_error  s     

'(

rG   c                r    [         R                  SUUS.05        U R                  R                  SS05        g )Nlog)close_status_codeclose_reasondoneT)loggerdebugr~   r   )rJ   r   r   r   s       rD   r   _SparkLLMClient.on_close  s7    ):$0	
 	

~&rG   c                    SSS.U l         [        R                  " U R                  UR                  UR
                  UR                  S95      nUR                  U5        g )NrS   ry   rz   )r   r   r7   )r   jsondumps
gen_paramsr   r   r7   send)rJ   r   rY   s      rD   r   _SparkLLMClient.on_open  sN    ,. DzzOObjjr  

 	rG   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: messagepayloadchoicesstatusr[   rW   rY      usage)r   loadsr~   r   r   r,   r   get)	rJ   r   r   rY   r   r   r   rW   
usage_datas	            rD   r   _SparkLLMClient.on_message  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
 rG   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)r   uidchatdomainr   r[   )r   	parameterr   r   zSpark Request Parameters: )r   r@   updater   r   )rJ   r   r   r7   rY   s        rD   r   _SparkLLMClient.gen_params  sm     "&W= 8T->->"?@!FH#56
 f%,,\:1$89rG   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)NrX   z-SparkLLMClient wait LLM api response timeout z secondsr   r   r   rY   )r~   r   EmptyTimeoutErrorConnectionError)rJ   r.   rW   _s       rD   r]   _SparkLLMClient.subscribe  s     **...9
 '!%gg&677'! W$M!  ;; "CG9HU s'   A=A 4A=A:&A55A::A=)	r    r"   r$   r   r   r7   r~   r@   r|   )NNN)r   r)   r    r)   r"   r)   r$   r   r@   r   r7   Optional[dict])r$   r)   r    r)   r"   r)   rk   r)   )NF)
r   
List[Dict]r   r)   r7   r   r,   r+   rk   None)
r   r   r   r)   r7   r   r,   r+   rk   zthreading.Thread)r   r   r   zOptional[Any]rk   r   )r   r   r   r/   r   r)   rk   r   )r   r   rk   r   )r   r   r   r)   rk   r   )N)r   listr   r)   r7   r   rk   rt   )r-   )r.   zOptional[int]rk   zGenerator[Dict, None, None])rn   ro   rp   rq   rr   r   staticmethodr   rg   r\   r   r   r   r   r   r]   rv   rI   rG   rD   rA   rA     s*    "&&*'+%% % 	%
 % $% %%< * *` (,  %	
  
: (,  %	
  
&	'8 LP'*:H	 rG   rA   )*
__future__r   r   r   r   r   loggingr~   r   r   r   timer   typingr   r   r	   r
   r   r   urllib.parser   r   r   wsgiref.handlersr   langchain_core.callbacksr   #langchain_core.language_models.llmsr   langchain_core.outputsr   langchain_core.utilsr   r   pydanticr   	getLoggerrn   r   r   rA   rI   rG   rD   <module>r      so    "           A A 8 8 - = 3 2 ? 			8	$i9s i9XO OrG   