U
    h                     @   s   d dl 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
mZ d dlmZ d dlmZ d dlmZmZ G dd dZG d	d
 d
eZG dd dZG dd deZdS )    N)AnyDict	GeneratorIteratorListOptionalUnion)CallbackManagerForLLMRun)LLM)GenerationChunk)get_from_dict_or_envpre_initc                   @   s   e Zd ZU dZdZeed< edddZee	j
eddd	Zee	j
eed
d
f dddZedddZdeee eee ef ee eedddZdeee eee ef ee ee dddZd
S )SVEndpointHandlerzy
    SambaNova Systems Interface for Sambaverse endpoint.

    :param str host_url: Base URL of the DaaS API service
    z/api/predictAPI_BASE_PATH)host_urlc                 C   s   || _ t | _dS )zr
        Initialize the SVEndpointHandler.

        :param str host_url: Base URL of the DaaS API service
        N)r   requestsSessionhttp_session)selfr    r   F/tmp/pip-unpacked-wheel-9gdii04g/langchain_community/llms/sambanova.py__init__   s    zSVEndpointHandler.__init__responsereturnc              
   C   s   i }z| j  d}|d }| jdkrt|drd}|dd D ]"}|t|d d d	 d
 7 }qH|d }t|}||d d d	 d< n
t|}W n. tk
r } zt||d< W 5 d}~X Y nX d|kr| j|d< |S )L  
        Processes the API response and returns the resulting dict.

        All resulting dicts, regardless of success or failure, will contain the
        `status_code` key with the API response status code.

        If the API returned an error, the resulting dict will contain the key
        `detail` with the error message.

        If the API call was successful, the resulting dict will contain the key
        `data` with the response data.

        :param requests.Response response: the response object to process
        :return: the response dict
        :type: dict
        
   error Nresult	responsesr   stream_token
completiondetailstatus_code)	textstripsplitr'   jsonloadsget	Exceptionstr)r   r!   Zlines_resultZtext_resultr%   lineer   r   r   _process_response   s&    

z#SVEndpointHandler._process_responseNc              
   c   s   zf|   D ]X}t|}d|kr*| j|d< |d dkr\|dr\dddigi|d< |  W S |V  q
W n0 tk
r } ztd| W 5 d	}~X Y nX d	S )
Process the streaming responser'   r   r   r"   r#   r    r!   %Error processing streaming response: N)
iter_linesr+   r,   r'   r-   r.   RuntimeError)r   r0   chunkr1   r   r   r   _process_streaming_responseD   s    


z-SVEndpointHandler._process_streaming_responser   c                 C   s   | j  | j S )z
        Return the full API URL for a given path.
        :returns: the full API URL for the sub-path
        :type: str
        )r   r   r   r   r   r   _get_full_urlU   s    zSVEndpointHandler._get_full_urlr    F)keysambaverse_model_nameinputparamsstreamr   c                 C   sF   |r|t |d}nd|i}| jj|  |d|d|d}t|S )Y  
        NLP predict using inline input string.

        :param str project: Project ID in which the endpoint exists
        :param str endpoint: Endpoint ID
        :param str key: API Key
        :param str input_str: Input string
        :param str params: Input params string
        :returns: Prediction results
        :type: dict
        instancer?   rC   application/jsonr<   zContent-TypeZ	modelNameheadersr+   )r+   r,   r   postr;   r   r2   )r   r<   r=   r>   r?   r@   datar   r   r   r   nlp_predict]   s    	zSVEndpointHandler.nlp_predict)r<   r=   r>   r?   r   c                 c   sX   |r|t |d}nd|i}| jj|  |d|d|dd}t|D ]
}|V  qHdS )rA   rB   rC   rD   rE   TrG   r+   r@   N)r+   r,   r   rH   r;   r   r8   )r   r<   r=   r>   r?   rI   r   r7   r   r   r   nlp_predict_stream   s    
z$SVEndpointHandler.nlp_predict_stream)r    F)r    )__name__
__module____qualname____doc__r   r/   __annotations__r   staticmethodr   Responser   r2   r   r8   r;   r   r   r   boolrJ   r   rL   r   r   r   r   r      s8   
	&  ' r   c                   @   s  e Zd ZU dZdZeed< dZeed< dZe	e ed< dZ
e	e ed< dZe	e ed	< G d
d dZeedddZe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dddZeeee ef eedddZeee ef e	ee  edddZeeee ef eee ddd Z d(eee ef e	ee  e	e! eee d!d"d#Z"eee ef e	ee  e	e! eeef ed!d$d%Z#d)eee ef e	ee  e	e! eed!d&d'Z$dS )*
Sambaversea  
    Sambaverse large language models.

    To use, you should have the environment variable ``SAMBAVERSE_API_KEY``
    set with your API key.

    get one in https://sambaverse.sambanova.ai
    read extra documentation in https://docs.sambanova.ai/sambaverse/latest/index.html


    Example:
    .. code-block:: python

        from langchain_community.llms.sambanova  import Sambaverse
        Sambaverse(
            sambaverse_url="https://sambaverse.sambanova.ai",
            sambaverse_api_key="your-sambaverse-api-key",
            sambaverse_model_name="Meta/llama-2-7b-chat-hf",
            streaming: = False
            model_kwargs={
                "select_expert": "llama-2-7b-chat-hf",
                "do_sample": False,
                "max_tokens_to_generate": 100,
                "temperature": 0.7,
                "top_p": 1.0,
                "repetition_penalty": 1.0,
                "top_k": 50,
                "process_prompt": False
            },
        )
    r    sambaverse_urlsambaverse_api_keyNr=   model_kwargsF	streamingc                   @   s   e Zd ZdZdS )zSambaverse.ConfigforbidNrM   rN   rO   extrar   r   r   r   Config   s   r]   r9   c                 C   s   dS NTr   clsr   r   r   is_lc_serializable   s    zSambaverse.is_lc_serializablevaluesr   c                 C   s8   t |dddd|d< t |dd|d< t |dd|d< |S )	z,Validate that api key exists in environment.rV   ZSAMBAVERSE_URLzhttps://sambaverse.sambanova.aidefaultrW   ZSAMBAVERSE_API_KEYr=   ZSAMBAVERSE_MODEL_NAMEr   r`   rc   r   r   r   validate_environment   s"    
    zSambaverse.validate_environmentc                 C   s   d| j iS zGet the identifying parameters.rX   rX   r:   r   r   r   _identifying_params   s    zSambaverse._identifying_paramsc                 C   s   dS )Return type of llm.zSambaverse LLMr   r:   r   r   r   	_llm_type   s    zSambaverse._llm_typestopr   c                 C   sb   | j pi }|dg }|p|}|s:ddd |D |d< dd | D }||d< t|}|S )1  
        Get the tuning parameters to use when calling the LLM.

        Args:
            stop: Stop words to use when generating. Model output is cut off at the
                first occurrence of any of the stop substrings.

        Returns:
            The tuning parameters as a JSON string.
        stop_sequences,c                 s   s   | ]}d | d V  qdS )"Nr   ).0xr   r   r   	<genexpr>  s    z0Sambaverse._get_tuning_params.<locals>.<genexpr>c                 S   s&   i | ]\}}|t |jt|d qS )typevaluerx   rM   r/   rt   kvr   r   r   
<dictcomp>  s    z1Sambaverse._get_tuning_params.<locals>.<dictcomp>)rX   r-   joinitemsr+   dumpsr   ro   Z_model_kwargsZ_kwarg_stop_sequencesZ_stop_sequencesZtuning_params_dicttuning_paramsr   r   r   _get_tuning_params   s    


zSambaverse._get_tuning_paramssdkpromptr   r   c           	   
   C   s   | | j| j||}|d dkr|d}|rt|d}|d}|d}td|d  d| d	| d
| d	ntd|d  d| d|d d d d S )a  
        Perform an NLP prediction using the Sambaverse endpoint handler.

        Args:
            sdk: The SVEndpointHandler to use for the prediction.
            prompt: The prompt to use for the prediction.
            tuning_params: The tuning parameters to use for the prediction.

        Returns:
            The prediction result.

        Raises:
            ValueError: If the prediction fails.
        r'   r   r   codedetailsmessage1Sambanova /complete call failed with status code .
Message: 

Details: 
Code: r   .r!   r"   r   r%   )rJ   rW   r=   r-   r6   )	r   r   r   r   r   r   optional_codeoptional_detailsoptional_messager   r   r   _handle_nlp_predict  s&       



 zSambaverse._handle_nlp_predictr   ro   r   c                 C   s"   t | j}| |}| |||S )a/  
        Perform a prediction using the Sambaverse endpoint handler.

        Args:
            prompt: The prompt to use for the prediction.
            stop: stop sequences.

        Returns:
            The prediction result.

        Raises:
            ValueError: If the prediction fails.
        )r   rV   r   r   r   r   ro   ss_endpointr   r   r   r   _handle_completion_requests<  s    

z&Sambaverse._handle_completion_requestsc                 c   s   | | j| j||D ]}|d dkr|d}|rx|d}|d}|d}td|d  d| d	| d
| d	ntd|d  d| d|d d d d }	t|	d}
|
V  qdS )O  
        Perform a streaming request to the LLM.

        Args:
            sdk: The SVEndpointHandler to use for the prediction.
            prompt: The prompt to use for the prediction.
            tuning_params: The tuning parameters to use for the prediction.

        Returns:
            An iterator of GenerationChunks.
        r'   r   r   r   r   r   r   r   r   r   r   r   r!   r"   r   r#   r(   N)rL   rW   r=   r-   
ValueErrorr6   r   r   r   r   r   r7   r   r   r   r   r(   Zgenerated_chunkr   r   r   _handle_nlp_predict_streamP  s*       



 
z%Sambaverse._handle_nlp_predict_streamr   ro   run_managerkwargsr   c           	   
   k   s   t | j}| |}z<| jrH| |||D ]}|r>||j |V  q*nW dS W n2 tk
r } ztd| |W 5 d}~X Y nX dS )a  Stream the Sambaverse's LLM on the given prompt.

        Args:
            prompt: The prompt to pass into the model.
            stop: Optional list of stop words to use when generating.
            run_manager: Callback manager for the run.
            kwargs: Additional keyword arguments. directly passed
                to the sambaverse model in API call.

        Returns:
            An iterator of GenerationChunks.
        N(Error raised by the inference endpoint: )	r   rV   r   rY   r   on_llm_new_tokenr(   r.   r   	r   r   ro   r   r   r   r   r7   r1   r   r   r   _streamx  s    

  

zSambaverse._streamc                 C   s0   d}| j f |||d|D ]}||j7 }q|S a  
        Perform a streaming request to the LLM.

        Args:
            prompt: The prompt to generate from.
            stop: Stop words to use when generating. Model output is cut off at the
                first occurrence of any of the stop substrings.
            run_manager: Callback manager for the run.
            kwargs: Additional keyword arguments. directly passed
                to the sambaverse model in API call.

        Returns:
            The model output as a string.
        r    )r   ro   r   r   r(   r   r   ro   r   r   r%   r7   r   r   r   _handle_stream_request  s      
z!Sambaverse._handle_stream_requestc              
   K   s^   z&| j r| ||||W S | ||W S  tk
rX } ztd| |W 5 d}~X Y nX dS )a  Run the LLM on the given input.

        Args:
            prompt: The prompt to generate from.
            stop: Stop words to use when generating. Model output is cut off at the
                first occurrence of any of the stop substrings.
            run_manager: Callback manager for the run.
            kwargs: Additional keyword arguments. directly passed
                to the sambaverse model in API call.

        Returns:
            The model output as a string.
        r   N)rY   r   r   r.   r   r   r   ro   r   r   r1   r   r   r   _call  s    zSambaverse._call)NN)NN)%rM   rN   rO   rP   rV   r/   rQ   rW   r=   r   rX   dictrY   rT   r]   classmethodra   r   r   rh   propertyr   rk   rm   r   r   r   r   r   r   r   r   r   r	   r   r   r   r   r   r   r   rU      sl   
 - 
  +  
%

  
rU   c                	   @   s   e Zd ZdZeedddZejedddZ	eje
eddf dd	d
ZeedddZdeeeeee ef ee eedddZdeeeeee ef ee ee dddZdS )SSEndpointHandlerz
    SambaNova Systems Interface for SambaStudio model endpoints.

    :param str host_url: Base URL of the DaaS API service
    r   api_base_uric                 C   s   || _ || _t | _dS )z
        Initialize the SSEndpointHandler.

        :param str host_url: Base URL of the DaaS API service
        :param str api_base_uri: Base URI of the DaaS API service
        N)r   r   r   r   r   )r   r   r   r   r   r   r     s    zSSEndpointHandler.__init__r   c              
   C   sV   i }z|  }W n. tk
r> } zt||d< W 5 d}~X Y nX d|krR|j|d< |S )r   r&   Nr'   )r+   r.   r/   r'   )r   r   r!   r1   r   r   r   r2     s    
z#SSEndpointHandler._process_responseNc           	   
   c   s  d| j krzddl}W n tk
r2   tdY nX ||}d}| D ]*}|jdkr\d}|j|j|jd}|V  qJ|r|  nd	| j ksd
| j krz4|	 D ]&}t
|}d|kr|j|d< |V  qW n0 tk
r } ztd| W 5 d}~X Y nX ntd| j  ddS )r3   api/predict/nlpr   NzTcould not import sseclient libraryPlease install it with `pip install sseclient-py`.FZerror_eventT)eventrI   r'   api/v2/predict/genericapi/predict/genericr'   r4   handling of endpoint uri:  not implemented)r   	sseclientImportErrorZ	SSEClienteventsr   rI   r'   closer5   r+   r,   r.   r6   r   )	r   r   r   clientZ
close_connr   r7   r0   r1   r   r   r   r8      sD    






"z-SSEndpointHandler._process_streaming_response)pathr   c                 C   s   | j  d| j d| S )z
        Return the full API URL for a given path.

        :param str path: the sub-path
        :returns: the full API URL for the sub-path
        :type: str
        /r   )r   r   r   r   r   r;   +  s    zSSEndpointHandler._get_full_urlr    F)projectendpointr<   r>   r?   r@   r   c           
      C   s   t |tr|g}d| jkr:|r0|t|d}qd|i}nxd| jkrvdd t|D }|rl|t|d}qd|i}n<d	| jkr|r|t|d
}qd|i}ntd| j d| jj| 	| d| d|i|d}	| 
|	S )rA   r   inputsr?   r   r   c                 S   s    g | ]\}}d | |dqS item)idry   r   rt   ir   r   r   r   
<listcomp>Q  s     z1SSEndpointHandler.nlp_predict.<locals>.<listcomp>r   r?   r   r   )	instancesr?   r   r   r   r   r<   rF   )
isinstancer/   r   r+   r,   	enumerater   r   rH   r;   r2   )
r   r   r   r<   r>   r?   r@   rI   r   r   r   r   r   rJ   5  s0    






zSSEndpointHandler.nlp_predict)r   r   r<   r>   r?   r   c           
      c   s  d| j kr:t|tr|g}|r0|t|d}qd|i}nd| j krt|trT|g}dd t|D }|r||t|d}qd|i}nNd	| j krt|tr|d
 }|r|t|d}qd|i}ntd| j  d| jj	| 
d| d| d|i|dd}| |D ]}	|	V  qdS )rA   r   r   r   r   c                 S   s    g | ]\}}d | |dqS r   r   r   r   r   r   r     s     z8SSEndpointHandler.nlp_predict_stream.<locals>.<listcomp>r   r   r   r   rB   rC   r   r   zstream/r   r<   TrK   N)r   r   r/   r+   r,   r   listr   r   rH   r;   r8   )
r   r   r   r<   r>   r?   rI   r   r   r7   r   r   r   rL   f  s<    








z$SSEndpointHandler.nlp_predict_stream)r    F)r    )rM   rN   rO   rP   r/   r   r   rS   r   r2   r   r8   r;   r   r   r   rT   rJ   r   rL   r   r   r   r   r     s6   +  7 r   c                   @   s  e Zd ZU dZdZeed< d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	< d
Zee ed< G dd dZeedddZeeeef dddZeedddZeeedddZeee  edddZeeee ef eedddZeee ef eee  eddd Zeeee ef ee e! dd!d"Z"d*eee ef eee  ee# ee e! d#d$d%Z$eee ef eee  ee# eeef ed#d&d'Z%d+eee ef eee  ee# eed#d(d)Z&dS ),SambaStudioa  
    SambaStudio large language models.

    To use, you should have the environment variables
    ``SAMBASTUDIO_BASE_URL`` set with your SambaStudio environment URL.
    ``SAMBASTUDIO_BASE_URI`` set with your SambaStudio api base URI.
    ``SAMBASTUDIO_PROJECT_ID`` set with your SambaStudio project ID.
    ``SAMBASTUDIO_ENDPOINT_ID`` set with your SambaStudio endpoint ID.
    ``SAMBASTUDIO_API_KEY``  set with your SambaStudio endpoint API key.

    https://sambanova.ai/products/enterprise-ai-platform-sambanova-suite

    read extra documentation in https://docs.sambanova.ai/sambastudio/latest/index.html

    Example:
    .. code-block:: python

        from langchain_community.llms.sambanova  import SambaStudio
        SambaStudio(
            sambastudio_base_url="your-SambaStudio-environment-URL",
            sambastudio_base_uri="your-SambaStudio-base-URI",
            sambastudio_project_id="your-SambaStudio-project-ID",
            sambastudio_endpoint_id="your-SambaStudio-endpoint-ID",
            sambastudio_api_key="your-SambaStudio-endpoint-API-key,
            streaming=False
            model_kwargs={
                "do_sample": False,
                "max_tokens_to_generate": 1000,
                "temperature": 0.7,
                "top_p": 1.0,
                "repetition_penalty": 1,
                "top_k": 50,
                #"process_prompt": False,
                #"select_expert": "Meta-Llama-3-8B-Instruct"
            },
        )
    r    sambastudio_base_urlsambastudio_base_urisambastudio_project_idsambastudio_endpoint_idsambastudio_api_keyNrX   FrY   c                   @   s   e Zd ZdZdS )zSambaStudio.ConfigrZ   Nr[   r   r   r   r   r]     s   r]   r9   c                 C   s   dS r^   r   r_   r   r   r   ra     s    zSambaStudio.is_lc_serializablec                 C   s   d| j iS ri   rj   r:   r   r   r   rk     s    zSambaStudio._identifying_paramsc                 C   s   dS )rl   zSambastudio LLMr   r:   r   r   r   rm     s    zSambaStudio._llm_typerb   c                 C   sX   t |dd|d< t |dddd|d< 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SAMBASTUDIO_BASE_URLr   ZSAMBASTUDIO_BASE_URIr   rd   r   ZSAMBASTUDIO_PROJECT_IDr   ZSAMBASTUDIO_ENDPOINT_IDr   ZSAMBASTUDIO_API_KEYrf   rg   r   r   r   rh     s6      
      z SambaStudio.validate_environmentrn   c                 C   sN   | j pi }|dg }|p|}d| jkr.|}ndd | D }t|}|S )rp   rq   r   c                 S   s&   i | ]\}}|t |jt|d qS rw   rz   r{   r   r   r   r~     s    z2SambaStudio._get_tuning_params.<locals>.<dictcomp>)rX   r-   r   r   r+   r   r   r   r   r   r     s    


zSambaStudio._get_tuning_paramsr   c                 C   s   | | j| j| j||}|d dkrd|d}|rLtd|d  d| ntd|d  d| d| jkr~|d d	 d
 S d| jkr|d d	 d d
 S d| jkr|d d	 d
 S td| j ddS )a  
        Perform an NLP prediction using the SambaStudio endpoint handler.

        Args:
            sdk: The SSEndpointHandler to use for the prediction.
            prompt: The prompt to use for the prediction.
            tuning_params: The tuning parameters to use for the prediction.

        Returns:
            The prediction result.

        Raises:
            ValueError: If the prediction fails.
        r'   r   r&   r   z.
 Details: z.
 response r   rI   r   r%   r   r   ry   r   Zpredictionsr   r   N)rJ   r   r   r   r-   r6   r   r   )r   r   r   r   r   Zoptional_detailr   r   r   r     s2    



zSambaStudio._handle_nlp_predictr   c                 C   s&   t | j| j}| |}| |||S )a0  
        Perform a prediction using the SambaStudio endpoint handler.

        Args:
            prompt: The prompt to use for the prediction.
            stop: stop sequences.

        Returns:
            The prediction result.

        Raises:
            ValueError: If the prediction fails.
        )r   r   r   r   r   r   r   r   r   r   N  s     
z'SambaStudio._handle_completion_requestsc                 c   s@  | | j| j| j||D ] }|d dkr|d}|r~|d}|d}|d}td|d  d| d	| d
| d	ntd|d  d| dd| jkrt	|d d }	ntd| jkr|d d d d d }	nPd| jkrt
|d d dkr|d d d d }	nd}	ntd| j dt|	d}
|
V  qdS )r   r'   r   r   r   r   r   r   r   r   r   r   r   r   rI   r#   r   r!   r   r   ry   r   r"   r    r   znot implementedr   N)rL   r   r   r   r-   r   r6   r   r+   r,   lenr   r   r   r   r   r   d  s@    




 


z&SambaStudio._handle_nlp_predict_streamr   c           	   
   k   s   t | j| j}| |}z<| jrL| |||D ]}|rB||j |V  q.nW dS W n2 tk
r } zt	d| |W 5 d}~X Y nX dS )   Call out to Sambanova's complete endpoint.

        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.
        Nr   )
r   r   r   r   rY   r   r   r(   r.   r   r   r   r   r   r     s$     
  

zSambaStudio._streamc                 C   s0   d}| j f |||d|D ]}||j7 }q|S r   r   r   r   r   r   r     s      
z"SambaStudio._handle_stream_requestc              
   K   sn   |dk	rt dz&| jr*| ||||W S | ||W S  t k
rh } ztd| |W 5 d}~X Y nX dS )r   Nzstop not implementedr   )r.   rY   r   r   r   r   r   r   r   r     s    zSambaStudio._call)NN)NN)'rM   rN   rO   rP   r   r/   rQ   r   r   r   r   rX   r   r   rY   rT   r]   r   ra   r   r   r   rk   rm   r   rh   r   r   r   r   r   r   r   r   r   r	   r   r   r   r   r   r   r   r     sp   
&  0 
  <  
$

  
r   )r+   typingr   r   r   r   r   r   r   r   Z langchain_core.callbacks.managerr	   Z#langchain_core.language_models.llmsr
   Zlangchain_core.outputsr   Zlangchain_core.utilsr   r   r   rU   r   r   r   r   r   r   <module>   s   $   2 K