U
    h&8                     @   s   d dl Z d dlZd dlmZ d dl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ZmZ d dlmZ d dlmZmZ d dlmZmZ d dlmZ d d	lmZ G d
d deZG dd deZdS )    N)ThreadPoolExecutor)AnyDictListMappingOptionalSequence	TypedDict)AsyncCallbackManagerForLLMRunCallbackManagerForLLMRun)BaseLLM)
Generation	LLMResult)Fieldroot_validatorget_from_dict_or_env)enforce_stop_tokensc                   @   s   e Zd ZU dZeed< dS )TrainResultzTrain result.lossN)__name__
__module____qualname____doc__float__annotations__ r   r   H/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/llms/gradient_ai.pyr      s   
r   c                   @   s  e Zd ZU dZedddZeed< dZe	e ed< dZ
e	e ed< dZe	e ed	< d
Zeed< dZe	ej ed< G dd dZeddeedddZedddeedddZeeeef dddZeedddZee eeef eeef dddZeeeef eeef d d!d"Zd1ee	ee  e	e eed#d$d%Z d2ee	ee  e	e! eed#d&d'Z"d3ee e	ee  e	e ee#d(d)d*Z$d4ee e	ee  e	e! ee#d(d+d,Z%ee ee&dd-d.Z'ee ee&dd/d0Z(dS )5GradientLLMa  Gradient.ai LLM Endpoints.

    GradientLLM is a class to interact with LLMs on gradient.ai

    To use, set the environment variable ``GRADIENT_ACCESS_TOKEN`` with your
    API token and ``GRADIENT_WORKSPACE_ID`` for your gradient workspace,
    or alternatively provide them as keywords to the constructor of this class.

    Example:
        .. code-block:: python

            from langchain_community.llms import GradientLLM
            GradientLLM(
                model="99148c6d-c2a0-4fbe-a4a7-e7c05bdb8a09_base_ml_model",
                model_kwargs={
                    "max_generated_token_count": 128,
                    "temperature": 0.75,
                    "top_p": 0.95,
                    "top_k": 20,
                    "stop": [],
                },
                gradient_workspace_id="12345614fc0_workspace",
                gradient_access_token="gradientai-access_token",
            )

    model   )aliasZ
min_lengthmodel_idNgradient_workspace_idgradient_access_tokenmodel_kwargszhttps://api.gradient.ai/apigradient_api_url
aiosessionc                   @   s   e Zd ZdZdZdS )zGradientLLM.ConfigTZforbidN)r   r   r   Zallow_population_by_field_nameextrar   r   r   r   ConfigL   s   r)   T)pre)valuesreturnc                 C   s4   t |dd|d< t |dd|d< t |dd|d< |S )z?Validate that api key and python package exists in environment.r$   ZGRADIENT_ACCESS_TOKENr#   ZGRADIENT_WORKSPACE_IDr&   ZGRADIENT_API_URLr   )clsr+   r   r   r   validate_environmentP   s           z GradientLLM.validate_environmentF)r*   Zskip_on_failurec                 C   s  zddl }W n0 tk
r*   td Y n tk
r<   Y nX |d dksZt|d dk rbtd|d dks~t|d dk rtd	|d
 r|d
 }d|dd  krdksn tdd|dd  krdksn tdd|ddkrtdd|ddkrtd|S )zPost init validation.r   NzdDeprecationWarning: `GradientLLM` will use `pip install gradientai` in future releases of langchain.r$   
   z0env variable `GRADIENT_ACCESS_TOKEN` must be setr#      z0env variable `GRADIENT_WORKSPACE_ID` must be setr%   temperatureg      ?   z-`temperature` must be in the range [0.0, 1.0]top_pz'`top_p` must be in the range [0.0, 1.0]top_kz`top_k` must be positivemax_generated_token_countz,`max_generated_token_count` must be positive)
gradientaiImportErrorloggingwarning	Exceptionlen
ValueErrorget)r-   r+   r6   kwr   r   r   	post_init`   s:    


zGradientLLM.post_init)r,   c                 C   s   | j pi }d| jid|iS )zGet the identifying parameters.r&   r%   )r%   r&   )self_model_kwargsr   r   r   _identifying_params   s    
zGradientLLM._identifying_paramsc                 C   s   dS )zReturn type of llm.Zgradientr   )r@   r   r   r   	_llm_type   s    zGradientLLM._llm_type)inputskwargsr,   c              	   C   s   | j pi }||}|dd}t| j d| j dd| j | j dddt|dkrftdd	 |D ntd
d	 t||D ddS )Build the kwargs for the Post request, used by sync

        Args:
            prompt (str): prompt used in query
            kwargs (dict): model kwargs in payload

        Returns:
            Dict[str, Union[str,dict]]: _description_
        multipliersN/models/z
/fine-tuneBearer application/jsonauthorizationzx-gradient-workspace-idacceptzcontent-typec                 s   s   | ]}d |iV  qdS )rD   Nr   ).0inputr   r   r   	<genexpr>   s    z=GradientLLM._kwargs_post_fine_tune_request.<locals>.<genexpr>c                 s   s    | ]\}}|d |idV  qdS )
multiplier)rD   ZfineTuningParametersNr   )rN   rO   rQ   r   r   r   rP      s    )Zsamplesurlheadersjson)	r%   r=   dictr&   r"   r$   r#   tuplezip)r@   rD   rE   rA   _paramsrG   r   r   r   _kwargs_post_fine_tune_request   s(    


z*GradientLLM._kwargs_post_fine_tune_request)promptrE   r,   c                 C   st   | j pi }||}t| j d| j dd| j | j dddt||dd|dd|d	d|d
dddS )rF   rH   z	/completerI   rJ   rK   r5   Nr1   r4   r3   )queryZmaxGeneratedTokenCountr1   ZtopKZtopPrR   )r%   rV   r&   r"   r$   r#   r=   )r@   r[   rE   rA   rY   r   r   r   _kwargs_post_request   s"    





z GradientLLM._kwargs_post_request)r[   stoprun_managerrE   r,   c              
   K   s   z:t jf | ||}|jdkr8td|j d|j W n4 t jjk
rn } ztd| W 5 d}~X Y nX | d }|dk	rt	||}|S )a  Call to Gradients API `model/{id}/complete`.

        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 model.
           5Gradient returned an unexpected response with status : 2RequestException while calling Gradient Endpoint: NgeneratedOutput)
requestspostr]   status_coder:   text
exceptionsRequestExceptionrU   r   )r@   r[   r^   r_   rE   responseerh   r   r   r   _call   s    
 
zGradientLLM._callc                    s  | j st 4 I dH j}|jf | j||d4 I dH :}|jdkrZtd|j d|j | I dH d }W 5 Q I dH R X W 5 Q I dH R X nf| j jf | j||d4 I dH :}|jdkrtd|j d|j | I dH d }W 5 Q I dH R X |dk	rt	||}|S )a  Async Call to Gradients API `model/{id}/complete`.

        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 model.
        N)r[   rE   r`   ra   rb   rd   )
r'   aiohttpClientSessionrf   r]   statusr:   rh   rU   r   )r@   r[   r^   r_   rE   sessionrk   rh   r   r   r   _acall  s.    
4
"

zGradientLLM._acall)promptsr^   r_   rE   r,   c              	      sr   t tt d fdd}t|dkr:tt||}n.ttdt|}t|||}W 5 Q R X t|dS )*Run the LLM on the given prompt and input.)r[   r,   c                    s    t jf | d dgS )N)r[   r^   r_   rh   )r   rm   )r[   rE   r_   r@   r^   r   r   _inner_generate>  s      z.GradientLLM._generate.<locals>._inner_generater2      generations)	strr   r   r;   listmapr   minr   )r@   rs   r^   r_   rE   rw   rz   pr   rv   r   	_generate4  s    
	zGradientLLM._generatec                    sD   g }t  fdd|D D ]}|t|dg q"t|dS )rt   c                 3   s(   | ] }j |fd  gV  qdS ))r^   r_   N)rr   )rN   r[   rv   r   r   rP   X  s   z)GradientLLM._agenerate.<locals>.<genexpr>ru   ry   )asyncioZgatherappendr   r   )r@   rs   r^   r_   rE   rz   Z
generationr   rv   r   
_agenerateO  s    zGradientLLM._ageneratec              
   K   s   z:t jf | ||}|jdkr8td|j d|j W n4 t jjk
rn } ztd| W 5 d }~X Y nX | }|d |d  }t	|dS )Nr`   ra   rb   rc   sumLossnumberOfTrainableTokensr   )
re   rf   rZ   rg   r:   rh   ri   rj   rU   r   )r@   rD   rE   rk   rl   response_jsonr   r   r   r   train_unsupervised_  s    

 zGradientLLM.train_unsupervisedc                    s  | j st 4 I d H t}|jf | ||4 I d H F}|jdkrXtd|j d|j | I d H }|d |d  }W 5 Q I d H R X W 5 Q I d H R X np| j jf | ||4 I d H F}|jdkrtd|j d|j | I d H }|d |d  }W 5 Q I d H R X t	|dS )Nr`   ra   rb   r   r   r   )
r'   rn   ro   rf   rZ   rp   r:   rh   rU   r   )r@   rD   rE   rq   rk   r   r   r   r   r   atrain_unsupervisedt  s6    

$

zGradientLLM.atrain_unsupervised)NN)NN)NN)NN))r   r   r   r   r   r"   r{   r   r#   r   r$   r%   rV   r&   r'   rn   ro   r)   r   r   r.   r?   propertyr   r   rB   rC   r   rZ   r]   r   r   rm   r
   rr   r   r   r   r   r   r   r   r   r   r   r      s   

* 

. 

#  
%  
/  
  
r   )r   r8   concurrent.futuresr   typingr   r   r   r   r   r   r	   rn   re   Zlangchain_core.callbacksr
   r   Z#langchain_core.language_models.llmsr   Zlangchain_core.outputsr   r   Zlangchain_core.pydantic_v1r   r   Zlangchain_core.utilsr   Zlangchain_community.llms.utilsr   r   r   r   r   r   r   <module>   s   $