a
    bgP                     @   sZ  d dl Z d dlZd dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZmZmZ d dl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mZmZmZmZ d
ZG dd deZ G dd de!eZ"G dd dZ#G dd de#Z$G dd de$Z%G dd de#Z&G dd de#Z'G dd de#Z(G dd de(Z)G dd deZ*G dd  d ee*Z+dS )!    N)abstractmethod)Enum)AnyDictListMappingOptional)CallbackManagerForLLMRun)BaseLLM)
Generation	LLMResult)convert_to_secret_strget_from_dict_or_env)	BaseModel
ConfigDict	SecretStrmodel_validator	validator2   c                   @   sF   e Zd ZdZdefeeeeddddZd
ee	e
 eeddd	ZdS )AzureMLEndpointClientz AzureML Managed Endpoint client. N)endpoint_urlendpoint_api_keydeployment_nametimeoutreturnc                 C   s,   |r|st d|| _|| _|| _|| _dS )zInitialize the class.zXA key/token and REST endpoint should 
                be provided to invoke the endpointN)
ValueErrorr   r   r   r   )selfr   r   r   r    r   w/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/site-packages/langchain_community/llms/azureml_endpoint.py__init__   s    zAzureMLEndpointClient.__init__)bodyrun_managerkwargsr   c                 K   s\   dd| j  d}| jdkr$| j|d< tj| j||}tjj||d| jd}|	 }|S )zcall.application/jsonzBearer )zContent-TypeAuthorizationr   zazureml-model-deploymentr   )r   )
r   r   urllibrequestRequestr   urlopengetr   read)r   r!   r"   r#   headersreqresponseresultr   r   r   call&   s    

zAzureMLEndpointClient.call)N)__name__
__module____qualname____doc__DEFAULT_TIMEOUTstrintr    bytesr   r	   r   r0   r   r   r   r   r      s"    r   c                   @   s   e Zd ZdZdZdZdZdS )AzureMLEndpointApiTypezAzure ML endpoints API types. Use `dedicated` for models deployed in hosted
    infrastructure (also known as Online Endpoints in Azure Machine Learning),
    or `serverless` for models deployed as a service with a
    pay-as-you-go billing or PTU.
    	dedicatedrealtime
serverlessN)r1   r2   r3   r4   r:   r;   r<   r   r   r   r   r9   @   s   r9   c                   @   s   e Zd ZU dZdZee ed< dZee ed< dZ	eed< e
eeddd	Zeee d
ddZejfeeeedddZeejfeeedddZdS )ContentFormatterBasezZTransform request and response of AzureML endpoint to match with
    required schema.
    r$   content_typeacceptszError while formatting response payload for chat model of type  `{api_type}`. Are you using the right formatter for the deployed  model and endpoint type?format_error_msg)promptr   c                 C   s6   dddddddd}|  D ]\}}| ||} q| S )	z*Escapes any special characters in `prompt`z\\z\"z\bz\fz\nz\rz\t)\"
	)itemsreplace)rA   Z
escape_mapZescape_sequenceZescaped_sequencer   r   r   escape_special_charactersy   s    z.ContentFormatterBase.escape_special_charactersr   c                 C   s   t jgS )zSupported APIs for the given formatter. Azure ML supports
        deploying models using different hosting methods. Each method may have
        a different API structure.r9   r:   r   r   r   r   supported_api_types   s    z(ContentFormatterBase.supported_api_typesrA   model_kwargsapi_typer   c                 C   s
   t  dS )zFormats the request body according to the input schema of
        the model. Returns bytes or seekable file like object in the
        format specified in the content_type request header.
        N)NotImplementedError)r   rA   rQ   rR   r   r   r   format_request_payload   s    
z+ContentFormatterBase.format_request_payloadoutputrR   r   c                 C   s   dS )zFormats the response body according to the output
        schema of the model. Returns the data type that is
        received from the response.
        Nr   )r   rV   rR   r   r   r   format_response_payload   s    z,ContentFormatterBase.format_response_payloadN)r1   r2   r3   r4   r>   r   r6   __annotations__r?   r@   staticmethodrK   propertyr   r9   rO   r:   r   r   rT   r   r8   r   rW   r   r   r   r   r=   L   s.   
 
r=   c                   @   sL   e Zd ZdZeee dddZee	ee
dddZe
eedd	d
ZdS )GPT2ContentFormatterzContent handler for GPT2rL   c                 C   s   t jgS NrM   rN   r   r   r   rO      s    z(GPT2ContentFormatter.supported_api_typesrP   c                 C   s2   t |}tdd| dgi|d}t|S )Ninput_stringrC   inputs
parametersr=   rK   jsondumpsr6   encoder   rA   rQ   rR   request_payloadr   r   r   rT      s
    
z+GPT2ContentFormatter.format_request_payloadrU   c              
   C   s`   zt |d d }W n> tttfyT } z t| jj|d|W Y d }~n
d }~0 0 t|dS )Nr   0rR   text	rb   loadsKeyError
IndexError	TypeErrorr   r@   formatr   r   rV   rR   choiceer   r   r   rW      s
    *z,GPT2ContentFormatter.format_response_payloadNr1   r2   r3   r4   rZ   r   r9   rO   r6   r   r8   rT   r   rW   r   r   r   r   r[      s   
r[   c                       s4   e Zd ZU dZdZeed< dd fddZ  ZS )OSSContentFormatterz`Deprecated: Kept for backwards compatibility

    Content handler for LLMs from the OSS catalog.Ncontent_formatterrL   c                    s   t    td d S )Nz`OSSContentFormatter` will be deprecated in the future. 
                      Please use `GPT2ContentFormatter` instead.  
                      superr    warningswarnrN   	__class__r   r   r       s    
zOSSContentFormatter.__init__	r1   r2   r3   r4   rv   r   rX   r    __classcell__r   r   r{   r   ru      s   
ru   c                   @   sL   e Zd ZdZeee dddZee	ee
dddZe
eedd	d
ZdS )HFContentFormatterz6Content handler for LLMs from the HuggingFace catalog.rL   c                 C   s   t jgS r\   rM   rN   r   r   r   rO      s    z&HFContentFormatter.supported_api_typesrP   c                 C   s.   t | td| dg|d}t|S )NrC   r^   ra   re   r   r   r   rT      s
    
z)HFContentFormatter.format_request_payloadrU   c              
   C   sd   zt |d d d }W n> tttfyX } z t| jj|d|W Y d }~n
d }~0 0 t|dS )Nr   rg   generated_textrh   ri   rk   rq   r   r   r   rW      s
    *z*HFContentFormatter.format_response_payloadNrt   r   r   r   r   r      s   
r   c                   @   sL   e Zd ZdZeee dddZee	ee
dddZe
eedd	d
ZdS )DollyContentFormatterz*Content handler for the Dolly-v2-12b modelrL   c                 C   s   t jgS r\   rM   rN   r   r   r   rO      s    z)DollyContentFormatter.supported_api_typesrP   c                 C   s2   t |}tdd| dgi|d}t|S )Nr]   rC   )
input_datar`   ra   re   r   r   r   rT      s    
z,DollyContentFormatter.format_request_payloadrU   c              
   C   s\   zt |d }W n> tttfyP } z t| jj|d|W Y d }~n
d }~0 0 t|dS )Nr   rh   ri   rk   rq   r   r   r   rW     s
    *z-DollyContentFormatter.format_response_payloadNrt   r   r   r   r   r      s   r   c                   @   sL   e Zd ZdZeee dddZee	ee
dddZe
eedd	d
ZdS )CustomOpenAIContentFormatterzAContent formatter for models that use the OpenAI like API scheme.rL   c                 C   s   t jt jgS r\   )r9   r:   r<   rN   r   r   r   rO     s    z0CustomOpenAIContentFormatter.supported_api_typesrP   c                 C   sr   t |}|tjtjfv r:tdd| dg|di}n.|tjkrXtd|i|}ntd| dt	
|S )z/Formats the request according to the chosen apir   rC   )r]   r`   rA   `api_type` # is not supported by this formatter)r=   rK   r9   r:   r;   rb   rc   r<   r   r6   rd   re   r   r   r   rT     s$    


z3CustomOpenAIContentFormatter.format_request_payloadrU   c              
   C   s   |t jt jfv rpzt|d d }W n> tttfyd } z t| j	j
|d|W Y d}~n
d}~0 0 t|dS |t jkrz(t|d d }t|tstdW n> tttfy } z t| j	j
|d|W Y d}~n
d}~0 0 t|d  t|d	|d
ddS td| ddS )zFormats responser   rg   rh   Nri   choicesziEndpoint response is not well formed for a chat model. Expected `dict` but `{type(choice)}` was received.rj   finish_reasonlogprobs)r   r   )rj   Zgeneration_infor   r   )r9   r:   r;   rb   rl   rm   rn   ro   r   r@   rp   r   r<   
isinstancedictstripr*   rq   r   r   r   rW   -  s4    *

*
z4CustomOpenAIContentFormatter.format_response_payloadNrt   r   r   r   r   r     s   r   c                       s4   e Zd ZU dZdZeed< dd fddZ  ZS )LlamaContentFormatterzNDeprecated: Kept for backwards compatibility

    Content formatter for Llama.Nrv   rL   c                    s   t    td d S )Nz`LlamaContentFormatter` will be deprecated in the future. 
                Please use `CustomOpenAIContentFormatter` instead.  
            rw   rN   r{   r   r   r    V  s    
zLlamaContentFormatter.__init__r}   r   r   r{   r   r   O  s   
r   c                   @   s  e Zd ZU dZdZeed< ejZ	eed< e
dZeed< dZeed< eZeed< dZeed	< d
Zeed< dZeed< dZee ed< eddZeddeeedddZedeeedddZ edeedddZ!edeeedddZ"ed	ddeee#ddd Z$dS )!AzureMLBaseEndpointz Azure ML Online Endpoint models.r   r   endpoint_api_typer   r   r   Nhttp_client   max_retriesrv   rQ   r   )Zprotected_namespacesbefore)mode)valuesr   c                 C   sd   t t|dd|d< t|dd|d< t|ddd|d< t|dd	tj|d< t|d
dtt|d
< |S )Nr   ZAZUREML_ENDPOINT_API_KEYr   ZAZUREML_ENDPOINT_URLr   ZAZUREML_DEPLOYMENT_NAMEr   r   ZAZUREML_ENDPOINT_API_TYPEr   ZAZUREML_TIMEOUT)r   r   r9   r:   r6   r5   )clsr   r   r   r   validate_environ  s,    
z$AzureMLBaseEndpoint.validate_environ)field_valuer   r   c                 C   s:   | d}||jvr6tdt| d|j d| d|S )z>Validate that content formatter is supported by endpoint type.r   zContent formatter fz8 is not supported by this endpoint. Supported types are z but endpoint is .)r*   rO   r   type)r   r   r   r   r   r   r   validate_content_formatter  s    

z.AzureMLBaseEndpoint.validate_content_formatter)r   r   c                 C   s,   | dr|dd }| dr(td|S )z'Validate that endpoint url is complete./Nzinference.ml.azure.comz`endpoint_url` should contain the full invocation URL including `/score` for `endpoint_api_type='dedicated'` or `/completions` or `/models/chat/completions` for `endpoint_api_type='serverless'`)endswithr   )r   r   r   r   r   validate_endpoint_url  s    

z)AzureMLBaseEndpoint.validate_endpoint_urlc                 C   sZ   | d}|tjks|tjkr0|ds0td|tjkrV|dsV|dsVtd|S )zBValidate that endpoint api type is compatible with the URL format.r   z/scorezEndpoints of type `dedicated` should follow the format `https://<your-endpoint>.<your_region>.inference.ml.azure.com/score`. If your endpoint URL ends with `/completions` or`/models/chat/completions`,use `endpoint_api_type='serverless'` instead.z/completionsz/models/chat/completionszEndpoints of type `serverless` should follow the format `https://<your-endpoint>.<your_region>.inference.ml.azure.com/completions` or `https://<your-endpoint>.<your_region>.inference.ml.azure.com/models/chat/completions`)r*   r9   r:   r;   r   r   r<   )r   r   r   r   r   r   r   validate_endpoint_api_type  s&    

z.AzureMLBaseEndpoint.validate_endpoint_api_typeT)alwaysc                 C   s@   | d}| d}| d}| dt}t|| ||}|S )z?Validate that api key and python package exists in environment.r   r   r   r   )r*   r5   r   Zget_secret_value)r   r   r   r   Zendpoint_keyr   r   r   r   r   r   validate_client  s    


z#AzureMLBaseEndpoint.validate_client)%r1   r2   r3   r4   r   r6   rX   r9   r:   r   r   r   r   r   r5   r   r7   r   r   r   rv   rQ   r   r   r   Zmodel_configr   classmethodr   r   r   r=   r   r   r   r   r   r   r   r   r   r   _  s4   


r   c                   @   sd   e Zd ZdZeeeef dddZeedddZ	de
e ee
e  ee eedd	d
ZdS )AzureMLOnlineEndpointa  Azure ML Online Endpoint models.

    Example:
        .. code-block:: python
            azure_llm = AzureMLOnlineEndpoint(
                endpoint_url="https://<your-endpoint>.<your_region>.inference.ml.azure.com/score",
                endpoint_api_type=AzureMLApiType.dedicated,
                endpoint_api_key="my-api-key",
                timeout=120,
                content_formatter=content_formatter,
            )
    rL   c                 C   s    | j pi }i d| jid|iS )zGet the identifying parameters.r   rQ   )rQ   r   )r   _model_kwargsr   r   r   _identifying_params  s    
z)AzureMLOnlineEndpoint._identifying_paramsc                 C   s   dS )zReturn type of llm.Zazureml_endpointr   rN   r   r   r   	_llm_type  s    zAzureMLOnlineEndpoint._llm_typeN)promptsstopr"   r#   r   c                 K   sv   | j pi }|| |r ||d< g }|D ]B}| j||| j}| jj||d}	| j|	| j}
||
g q(t	|dS )an  Run the LLM on the given prompts.

        Args:
            prompts: The prompt to pass into the model.
            stop: Optional list of stop words to use when generating.
        Returns:
            The string generated by the model.
        Example:
            .. code-block:: python
                response = azureml_model.invoke("Tell me a joke.")
        r   )r!   r"   )generations)
rQ   updaterv   rT   r   r   r0   rW   appendr   )r   r   r   r"   r#   r   r   rA   rf   Zresponse_payloadr   r   r   r   	_generate  s"    

zAzureMLOnlineEndpoint._generate)NN)r1   r2   r3   r4   rZ   r   r6   r   r   r   r   r   r	   r   r   r   r   r   r   r     s     
r   ),rb   urllib.requestr&   ry   abcr   enumr   typingr   r   r   r   r   Z langchain_core.callbacks.managerr	   Z#langchain_core.language_models.llmsr
   Zlangchain_core.outputsr   r   Zlangchain_core.utilsr   r   Zpydanticr   r   r   r   r   r5   objectr   r6   r9   r=   r[   ru   r   r   r   r   r   r   r   r   r   r   <module>   s.   /`B 