a
    bgz;                     @  sl  d dl m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 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mZ d dlmZ d d	l m!Z! d d
l"m#Z#m$Z$m%Z%m&Z&m'Z' e(e)Z*edZ+dddddZ,dddddZ-ddddddZ.ddddddZ/ddddddZ0ddddd Z1d!d"dd#d$Z2G d%d deZ3dS )&    )annotationsN)AnyAsyncIterableAsyncIteratorCallableDictIterableIteratorListMappingOptionalTupleTypeVar)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)BaseLLM)
GenerationGenerationChunk	LLMResult)get_from_dict_or_envpre_init)Field)	HTTPError)before_sleep_logretryretry_if_exception_typestop_after_attemptwait_exponentialTTongyizCallable[[Any], Any])llmreturnc                 C  s6   d}d}t dt| jtd||dtttttj	dS )N      T)
multiplierminmax)reraisestopwaitr   before_sleep)
r   r   max_retriesr   r   r   r   loggerloggingWARNING)r    Zmin_secondsZmax_seconds r/   m/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/llms/tongyi.py_create_retry_decorator*   s    
r1   r   )respr!   c                 C  sr   | d dkr| S | d dv rDt d| d  d| d  d| d  n*td	| d  d| d  d| d  | d
dS )z,Check the response from the completion call.status_code   )i  i  zstatus_code: z	 
 code: codez 
 message: messagez"HTTP error occurred: status_code: )responseN)
ValueErrorr   )r2   r/   r/   r0   check_response8   s$    r9   )r    kwargsr!   c                   s.   t  }|ddd fdd}|f i |S )*Use tenacity to retry the completion call.r   _kwargsr!   c                    s    j jf i | }t|S Nclientcallr9   )r=   r2   r    r/   r0   _generate_with_retryM   s    z1generate_with_retry.<locals>._generate_with_retryr1   )r    r:   retry_decoratorrC   r/   rB   r0   generate_with_retryI   s    rF   c                   s.   t  }|ddd fdd}|f i |S )r;   r   r<   c                  ;  s*    j jf i | }|D ]}t|V  qd S r>   r?   )r=   	responsesr2   rB   r/   r0   _stream_generate_with_retryY   s    z?stream_generate_with_retry.<locals>._stream_generate_with_retryrD   )r    r:   rE   rH   r/   rB   r0   stream_generate_with_retryU   s    rI   c                 K s8   G dd d}|| fi |2 z3 dH W }|V  q6 dS )zAsync version of `stream_generate_with_retry`.

    Because the dashscope SDK doesn't provide an async API,
    we wrap `stream_generate_with_retry` with an async generator.c                   @  sF   e Zd ZdddddZdddd	Zddd
dZddddZdS )z8astream_generate_with_retry.<locals>._AioTongyiGeneratorr   r   )_llmr=   c                 [  s   t |fi || _d S r>   )rI   	generator)selfrJ   r=   r/   r/   r0   __init__i   s    zAastream_generate_with_retry.<locals>._AioTongyiGenerator.__init__zAsyncIterator[Any]r!   c                 S  s   | S r>   r/   rL   r/   r/   r0   	__aiter__l   s    zBastream_generate_with_retry.<locals>._AioTongyiGenerator.__aiter__c                   s,   t  d | jI d H }|d ur$|S td S r>   )asyncioget_running_looprun_in_executor
_safe_nextStopAsyncIteration)rL   valuer/   r/   r0   	__anext__o   s    
zBastream_generate_with_retry.<locals>._AioTongyiGenerator.__anext__c                 S  s&   zt | jW S  ty    Y d S 0 d S r>   )nextrK   StopIterationrO   r/   r/   r0   rT   x   s    zCastream_generate_with_retry.<locals>._AioTongyiGenerator._safe_nextN)__name__
__module____qualname__rM   rP   rW   rT   r/   r/   r/   r0   _AioTongyiGeneratorh   s   	r]   Nr/   )r    r:   r]   chunkr/   r/   r0   astream_generate_with_retryb   s    r_   zIterable[T]zIterator[Tuple[T, bool]])iterabler!   c                 c  sP   t | }zt|}W n ty(   Y dS 0 |D ]}|dfV  |}q.|dfV  dS )z[Generate elements from an iterable,
    and a boolean indicating if it is the last element.NFT)iterrX   rY   r`   iteratoritemZ	next_itemr/   r/   r0   generate_with_last_element_mark   s    
re   zAsyncIterable[T]zAsyncIterator[Tuple[T, bool]]c                 C s`   |   }z| I dH }W n ty.   Y dS 0 |2 z3 dH W }|dfV  |}q46 |dfV  dS )zaGenerate elements from an async iterable,
    and a boolean indicating if it is the last element.NFT)rP   rW   rU   rb   r/   r/   r0    agenerate_with_last_element_mark   s    
rf   c                      s~  e Zd ZU dZeddddZdZded< ed	d
dZ	ded< ee
dZde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ddddZeddd d!d"Zeddd#d$Zed%d fd&d'ZdEd(d)d*dd+d,d-d.ZdFd(d)d/dd+d,d0d1ZdGdd)d*dd2d3d4d5ZdHdd)d/dd6d3d7d8Zdddd9d:d;ZedIdddd=d>d?Zed@dAdBdCdDZ  ZS )Jr   uP	  Tongyi completion model integration.

    Setup:
        Install ``dashscope`` and set environment variables ``DASHSCOPE_API_KEY``.

        .. code-block:: bash

            pip install dashscope
            export DASHSCOPE_API_KEY="your-api-key"

    Key init args — completion params:
        model: str
            Name of Tongyi model to use.
        top_p: float
            Total probability mass of tokens to consider at each step.
        streaming: bool
            Whether to stream the results or not.

    Key init args — client params:
        api_key: Optional[str]
            Dashscope API KEY. If not passed in will be read from env var DASHSCOPE_API_KEY.
        max_retries: int
            Maximum number of retries to make when generating.

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

    Instantiate:
        .. code-block:: python

            from langchain_community.llms import Tongyi

            llm = Tongyi(
                model="qwen-max",
                # top_p="...",
                # api_key="...",
                # 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

            '探索、成长、连接与爱。在有限的时间里，寻找个人价值，贡献于他人和社会，体验丰富多彩的情感与经历，不断学习进步，让世界因自己的存在而更美好。'

    zDict[str, str]rN   c                 C  s   ddiS )Ndashscope_api_keyDASHSCOPE_API_KEYr/   rO   r/   r/   r0   
lc_secrets   s    zTongyi.lc_secretsNr   r@   z	qwen-plusmodel)defaultaliasstr
model_name)default_factoryzDict[str, Any]model_kwargsg?floattop_papi_keyzOptional[str]rg   Fbool	streaming
   intr+   c                 C  s   dS )zReturn type of llm.Ztongyir/   rO   r/   r/   r0   	_llm_type  s    zTongyi._llm_typer   )valuesr!   c                 C  sj   t |ddgd|d< zddl}W n ty:   tdY n0 z|j|d< W n tyd   tdY n0 |S )	z?Validate that api key and python package exists in environment.rg   rs   rh   r   NzZCould not import dashscope python package. Please install it with `pip install dashscope`.r@   z`dashscope` has no `Generation` attribute, this is likely due to an old version of the dashscope package. Try upgrading it with `pip install --upgrade dashscope`.)r   	dashscopeImportErrorr   AttributeErrorr8   )clsry   rz   r/   r/   r0   validate_environment  s     


zTongyi.validate_environmentc                 C  s    | j | j| jd}i || jS )z7Get the default parameters for calling Tongyi Qwen API.)rj   rr   rs   )rn   rr   rg   rp   )rL   Znormal_paramsr/   r/   r0   _default_params   s
    zTongyi._default_paramszMapping[str, Any]c                   s   d| j it jS )Nrn   )rn   super_identifying_paramsrO   	__class__r/   r0   r   +  s    zTongyi._identifying_paramsz	List[str]zOptional[List[str]]z"Optional[CallbackManagerForLLMRun]r   )promptsr(   run_managerr:   r!   c              	   K  s   g }| j rxt|dkrtdd }| j|d ||fi |D ]}|d u rN|}q<||7 }q<|d usdJ || |g nN| jf d|i|}|D ]4}	t| fd|	i|}
|tf i | 	|
g qt
|d| jidS )Nr"   ,Cannot stream results with multiple prompts.r   r(   promptrn   generationsZ
llm_output)ru   lenr8   _streamappend_chunk_to_generation_invocation_paramsrF   r   _generation_from_qwen_respr   rn   rL   r   r(   r   r:   r   Z
generationr^   paramsr   
completionr/   r/   r0   	_generate/  s,    
zTongyi._generatez'Optional[AsyncCallbackManagerForLLMRun]c              
     s   g }| j rt|dkrtdd }| j|d ||fi |2 z"3 d H W }|d u rV|}q<||7 }q<6 |d usnJ || |g nh| jf d|i|}|D ]N}	t 	d t
jtfi | |	d|I d H }
|tf i | |
g qt|d| jidS )Nr"   r   r   r(   )r    r   rn   r   )ru   r   r8   _astreamr   r   r   rQ   rR   rS   	functoolspartialrF   r   r   r   rn   r   r/   r/   r0   
_agenerateP  s:    &
zTongyi._ageneratezIterator[GenerationChunk])r   r(   r   r:   r!   c           	      k  sp   | j f |dd|}tt| fd|i|D ]<\}}tf i | ||}|rd|j|j|| jd |V  q.d S NT)r(   streamr   )r^   verbose)r   re   rI   r   r   on_llm_new_tokentextr   	rL   r   r(   r   r:   r   Zstream_respis_last_chunkr^   r/   r/   r0   r   v  s$    
zTongyi._streamzAsyncIterator[GenerationChunk]c           	      K s   | j f |dd|}tt| fd|i|2 zJ3 d H W \}}tf i | ||}|rr|j|j|| jdI d H  |V  q.6 d S r   )r   rf   r_   r   r   r   r   r   r   r/   r/   r0   r     s$    
zTongyi._astream)r(   r:   r!   c                 K  s4   i | j |}|d ur||d< |dr0d|d< |S )Nr(   r   TZincremental_output)r   get)rL   r(   r:   r   r/   r/   r0   r     s    
zTongyi._invocation_paramsT)r2   r   r!   c                 C  sL   |r6t | d d t | d d | d t | d ddS t | d d dS d S )	Noutputr   finish_reason
request_idusage)r   r   Ztoken_usager   generation_info)r   )dict)r2   r   r/   r/   r0   r     s    


	z!Tongyi._generation_from_qwen_respr   r   )r^   r!   c                 C  s   t | j| jdS )Nr   )r   r   r   )r^   r/   r/   r0   r     s    zTongyi._chunk_to_generation)NN)NN)NN)NN)T)rZ   r[   r\   __doc__propertyri   r@   __annotations__r   rn   r   rp   rr   rg   ru   r+   rx   r   r~   r   r   r   r   r   r   r   staticmethodr   r   __classcell__r/   r/   r   r0   r      sH   
L
  $  )     )4
__future__r   rQ   r   r-   typingr   r   r   r   r   r   r	   r
   r   r   r   r   Zlangchain_core.callbacksr   r   Z#langchain_core.language_models.llmsr   Zlangchain_core.outputsr   r   r   Zlangchain_core.utilsr   r   Zpydanticr   Zrequests.exceptionsr   tenacityr   r   r   r   r   	getLoggerrZ   r,   r   r1   r9   rF   rI   r_   re   rf   r   r/   r/   r/   r0   <module>   s*   8
 