o
    Zh[z                     @   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 d dlmZmZ d dl	mZ G d	d
 d
eZG dd deZdS )    N)AnyDictIteratorListOptionalTupleUnion)CallbackManagerForLLMRun)LLM)GenerationChunk)convert_to_secret_strget_from_dict_or_env)Field	SecretStr)Responsec                       s2  e Zd ZU dZeddZeed< 	 eeddZ	eed< 	 edddZ
eed< 	 edddZeed	< 	 ed
dZeed< 	 dZeeeef  ed< 	 G dd dZedefddZedeeef fddZedeeef fddZedefddZdeddf fddZdedeeef fddZd/deee  deeef fd d!Z		
d0d"eee ef deee  dee defd#d$Z d%edefd&d'Z!d%ede"e# fd(d)Z$		d1d"eee ef deee  d*ee% dede"e# f
d+d,Z&		d1d"eee ef deee  d*ee% dedef
d-d.Z'  Z(S )2SambaStudiou  
    SambaStudio large language models.

    Setup:
        To use, you should have the environment variables
        ``SAMBASTUDIO_URL`` set with your SambaStudio environment URL.
        ``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_url="your-SambaStudio-environment-URL",
                sambastudio_api_key="your-SambaStudio-API-key,
                model_kwargs={
                    "model" : model or expert name (set for Bundle endpoints),
                    "max_tokens" : max number of tokens to generate,
                    "temperature" : model temperature,
                    "top_p" : model top p,
                    "top_k" : model top k,
                    "do_sample" : wether to do sample
                    "process_prompt": wether to process prompt
                        (set for Bundle generic v1 and v2 endpoints)
                },
            )
    Key init args — completion params:
        model: str
            The name of the model to use, e.g., Meta-Llama-3-70B-Instruct-4096
            (set for Bundle endpoints).
        streaming: bool
            Whether to use streaming handler when using non streaming methods
        model_kwargs: dict
            Extra Key word arguments to pass to the model:
                max_tokens: int
                    max tokens to generate
                temperature: float
                    model temperature
                top_p: float
                    model top p
                top_k: int
                    model top k
                do_sample: bool
                    wether to do sample
                process_prompt:
                    wether to process prompt
                    (set for Bundle generic v1 and v2 endpoints)
    Key init args — client params:
        sambastudio_url: str
            SambaStudio endpoint Url
        sambastudio_api_key: str
            SambaStudio endpoint api key

    Instantiate:
        .. code-block:: python

            from langchain_community.llms import SambaStudio

            llm = SambaStudio=(
                sambastudio_url = set with your SambaStudio deployed endpoint URL,
                sambastudio_api_key = set with your SambaStudio deployed endpoint Key,
                model_kwargs = {
                    "model" : model or expert name (set for Bundle endpoints),
                    "max_tokens" : max number of tokens to generate,
                    "temperature" : model temperature,
                    "top_p" : model top p,
                    "top_k" : model top k,
                    "do_sample" : wether to do sample
                    "process_prompt" : wether to process prompt
                        (set for Bundle generic v1 and v2 endpoints)
                }
            )

    Invoke:
        .. code-block:: python
            prompt = "tell me a joke"
            response = llm.invoke(prompt)

    Stream:
        .. code-block:: python

        for chunk in llm.stream(prompt):
            print(chunk, end="", flush=True)

    Async:
        .. code-block:: python

        response = llm.ainvoke(prompt)
        await response

     defaultsambastudio_urlsambastudio_api_keyT)r   excludebase_urlstreaming_urlF	streamingNmodel_kwargsc                   @      e Zd ZdZdS )zSambaStudio.ConfigTN__name__
__module____qualname__Zpopulate_by_name r!   r!   Y/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/llms/sambanova.pyConfig|       r#   returnc                 C      dS )9Return whether this model can be serialized by Langchain.Tr!   clsr!   r!   r"   is_lc_serializable      zSambaStudio.is_lc_serializablec                 C   s
   dddS )Nr   r   )r   r   r!   selfr!   r!   r"   
lc_secrets   s   zSambaStudio.lc_secretsc                 C   s   d| j id| jiS )Return a dictionary of identifying parameters.

        This information is used by the LangChain callback system, which
        is used for tracing purposes make it possible to monitor LLMs.
        r   r   )r   r   r,   r!   r!   r"   _identifying_params   s   zSambaStudio._identifying_paramsc                 C   r&   )zReturn type of llm.zsambastudio-llmr!   r,   r!   r!   r"   	_llm_type   r+   zSambaStudio._llm_typekwargsc                    sT   t |dd|d< tt |dd|d< | |d \|d< |d< t jdi | dS )	'init and validate environment variablesr   ZSAMBASTUDIO_URLr   ZSAMBASTUDIO_API_KEYr   r   Nr!   )r   r   _get_sambastudio_urlssuper__init__r-   r2   	__class__r!   r"   r6      s   
zSambaStudio.__init__urlc                 C   sd   d|v r|}|}||fS d|v r| dd}|}||fS |}d|v r.d|d}||fS td)a3  
        Get streaming and non streaming URLs from the given URL

        Args:
            url: string with sambastudio base or streaming endpoint url

        Returns:
            base_url: string with url to do non streaming calls
            streaming_url: string with url to do streaming calls
        chat/completionsstreamzstream/r   Zgenericzgeneric/streamUnsupported URL)replacejoinsplit
ValueError)r-   r:   r   Z
stream_urlr!   r!   r"   r4      s   z!SambaStudio._get_sambastudio_urlsstopc                 C   sB  |du rg }| j p
i }|dg | }t|dkr||d< d| jv rKd| v r/|d|d< d| v r<|d|d< d	| v rG|d	 |}|S d
| jv rnd| v r]|d|d< d| v rj|d|d< |}|S d| jv rd| v r|d|d< d| v r|d|d< dd | D }|S td| j d)aD  
        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 in the format required by api to use
        NZstop_sequencesr   r;   Zselect_expertmodelZmax_tokens_to_generate
max_tokensprocess_promptapi/v2/predict/genericapi/predict/genericc                 S   s&   i | ]\}}|t |jt|d qS ))typevalue)rH   r   str).0kvr!   r!   r"   
<dictcomp>   s    z2SambaStudio._get_tuning_params.<locals>.<dictcomp>r=   9only openai, generic v1 and generic v2 APIs are supported)r   getlenr   keyspopitemsrA   )r-   rB   Z_model_kwargsZ_stop_sequencesZtuning_paramsr!   r!   r"   _get_tuning_params   sP   




zSambaStudio._get_tuning_paramspromptc                 C   s  t |tr|g}| |}d| jv r6d|d dg}||d|}dd | D }d| j  d	d
}nd| jv rq|ddrQt	ddd|d dgd}n|d }d|dg}dd | D }||d}d| j i}nLd| jv r|ddr|d ddkrt	ddd|d dgd}n	|d }n|d }|r||d}n|g|d}d| j i}n	t
d| j dt }	|r|	j| j||dd}
n
|	j| j||dd}
|
jd krtd!|
j d"|
j d"|
S )#a  
        Performs a post request to the LLM API.

        Args:
        prompt: The prompt to pass into the model
        stop: list of stop tokens
        streaming: wether to do a streaming call

        Returns:
            A request Response object
        r;   userr   rolecontent)messagesr<   c                 S      i | ]\}}|d ur||qS Nr!   rK   keyrI   r!   r!   r"   rN         z/SambaStudio._handle_request.<locals>.<dictcomp>Bearer application/jsonAuthorizationzContent-TyperF   rE   Fzsambaverse-conversation-idN)Z
message_idrY   rZ   )Zconversation_idr[   Zitem0)idrI   c                 S   r\   r]   r!   r^   r!   r!   r"   rN   2  r`   )rT   paramsr_   rG   rI   True)instancerf   )Z	instancesrf   r=   rO   Theadersjsonr<      2Sambanova / complete call failed with status code .)
isinstancerJ   rU   r   rT   r   get_secret_valuerP   rk   dumpsrA   requestsSessionpostr   r   status_codeRuntimeErrortext)r-   rV   rB   r   rf   messages_dictdatarj   rT   http_sessionresponser!   r!   r"   _handle_request  s~   



	





zSambaStudio._handle_requestr{   c              
   C   s   z|  }W n ty } ztd| d|j d}~ww d| jv r/|d d d d }|S d	| jv r@|d
 d d d }|S d| jv rO|d d d }|S td| j d)
        Process a non streaming response from the api

        Args:
            response: A request Response object

        Returns
            completion: a string with model generation
        ;Sambanova /complete call failed couldn't get JSON response 
response: Nr;   choicesr   messagerZ   rF   rT   rI   
completionrG   Zpredictionsr=   rO   )rk   	Exceptionrv   rw   r   rA   r-   r{   Zresponse_dicter   r!   r!   r"   _process_responseh  s,   

	
zSambaStudio._process_responsec           
      c   sL   zddl }W n ty   tdw d| jv r||}| D ]{}|jdkr5td|j d|j dzP|jdkrt	|jt
rHt|j}ntd|j d|j d|d	rgtd|j d|j dt|d
 dkrz|d
 d d d }nd}t|d}|V  W q! ty } ztd| d|j d}~ww dS d| jv r| D ]3}	zt|	}|d d d d d }t|d}|V  W q ty } z
td| d|	 d}~ww dS d| jv r| D ]2}	zt|	}|d d d d }t|d}|V  W q ty } z
td| d|	 d}~ww dS td| j d)
        Process a streaming response from the api

        Args:
            response: An iterable request Response object

        Yields:
            GenerationChunk: a GenerationChunk with model partial generation
        r   NTcould not import sseclient libraryPlease install it with `pip install sseclient-py`.r;   error_event1Sambanova /complete call failed with status code rn   [DONE]errorr   deltarZ   r   rw   3Error getting content chunk raw streamed response: data: rF   resultrT   rI   Zstream_tokenzline: rG   	responsesr=   rO   )	sseclientImportErrorr   	SSEClienteventseventrv   ru   ry   ro   rJ   rk   loadsrP   rQ   r   r   
iter_linesrA   )
r-   r{   r   clientr   ry   rZ   generated_chunkr   liner!   r!   r"   _process_stream_response  s   






&





z$SambaStudio._process_stream_responserun_managerc                 k   <    | j ||dd}| |D ]}|r||j |V  qdS )a\  Call out to Sambanova's complete endpoint.

        Args:
            prompt: The prompt to pass into the model.
            stop: a list of strings on which the model should stop generating.
            run_manager: A run manager with callbacks for the LLM.
        Yields:
            chunk: GenerationChunk with model partial generation
        Tr   Nr|   r   Zon_llm_new_tokenrw   r-   rV   rB   r   r2   r{   chunkr!   r!   r"   _stream     zSambaStudio._streamc                 K   T   | j rd}| jd|||d|D ]}||j7 }q|S | j||dd}| |}|S )a  Call out to Sambanova's complete endpoint.

        Args:
            prompt: The prompt to pass into the model.
            stop: a list of strings on which the model should stop generating.

        Returns:
            result: string with model generation
        r   rV   rB   r   Fr   Nr!   r   r   rw   r|   r   r-   rV   rB   r   r2   r   r   r{   r!   r!   r"   _call     

zSambaStudio._callr]   NFNN))r   r   r    __doc__r   r   rJ   __annotations__r   r   r   r   r   boolr   r   r   r   r#   classmethodr*   propertyr.   r0   r1   r6   r   r4   r   rU   r   r   r|   r   r   r   r   r	   r   r   __classcell__r!   r!   r8   r"   r      s   
 \$D

f$b


r   c                       s2  e Zd ZU dZeddZeed< 	 eeddZ	eed< 	 eddZ
eed< 	 eddZeed	< 	 ed
dZeed< 	 eddZeed< 	 eddZee ed< 	 eddZee ed< 	 eddidZeed< 	 G dd dZedefddZedeeef fddZedeeef fddZedefddZdeddf fd d!Z		d0d"e e!e ef d#ee!e  d	ee de"fd$d%Z#d&e"defd'd(Z$d&e"de%e& fd)d*Z'		d1d"e e!e ef d#ee!e  d+ee( dedef
d,d-Z)		d1d"e e!e ef d#ee!e  d+ee( dede%e& f
d.d/Z*  Z+S )2SambaNovaCloudu  
    SambaNova Cloud large language models.

    Setup:
        To use, you should have the environment variables:
        ``SAMBANOVA_URL`` set with SambaNova Cloud URL.
        defaults to http://cloud.sambanova.ai/
        ``SAMBANOVA_API_KEY`` set with your SambaNova Cloud API Key.
        Example:
        .. code-block:: python
            from langchain_community.llms.sambanova  import SambaNovaCloud
            SambaNovaCloud(
                sambanova_api_key="your-SambaNovaCloud-API-key,
                model = model name,
                max_tokens = max number of tokens to generate,
                temperature = model temperature,
                top_p = model top p,
                top_k = model top k
            )
    Key init args — completion params:
        model: str
            The name of the model to use, e.g., Meta-Llama-3-70B-Instruct-4096
            (set for CoE endpoints).
        streaming: bool
            Whether to use streaming handler when using non streaming methods
        max_tokens: int
            max tokens to generate
        temperature: float
            model temperature
        top_p: float
            model top p
        top_k: int
            model top k

    Key init args — client params:
        sambanova_url: str
            SambaNovaCloud Url defaults to http://cloud.sambanova.ai/
        sambanova_api_key: str
            SambaNovaCloud api key
    Instantiate:
        .. code-block:: python
            from langchain_community.llms.sambanova  import SambaNovaCloud
            SambaNovaCloud(
                sambanova_api_key="your-SambaNovaCloud-API-key,
                model = model name,
                max_tokens = max number of tokens to generate,
                temperature = model temperature,
                top_p = model top p,
                top_k = model top k
            )
    Invoke:
        .. code-block:: python
            prompt = "tell me a joke"
            response = llm.invoke(prompt)
    Stream:
        .. code-block:: python
        for chunk in llm.stream(prompt):
            print(chunk, end="", flush=True)
    Async:
        .. code-block:: python
        response = llm.ainvoke(prompt)
        await response
    r   r   sambanova_urlsambanova_api_keyzMeta-Llama-3.1-8B-InstructrC   Fr   i   rD   gffffff?temperatureNtop_ptop_kZinclude_usageTstream_optionsc                   @   r   )zSambaNovaCloud.ConfigTNr   r!   r!   r!   r"   r#   {  r$   r#   r%   c                 C   r&   )r'   Fr!   r(   r!   r!   r"   r*   ~  r+   z!SambaNovaCloud.is_lc_serializablec                 C   s   ddiS )Nr   r!   r,   r!   r!   r"   r.     s   zSambaNovaCloud.lc_secretsc                 C   s"   | j | j| j| j| j| j| jdS )r/   rC   r   rD   r   r   r   r   r   r,   r!   r!   r"   r0     s   z"SambaNovaCloud._identifying_paramsc                 C   r&   )z7Get the type of language model used by this chat model.zsambanovacloud-llmr!   r,   r!   r!   r"   r1     r+   zSambaNovaCloud._llm_typer2   c                    s>   t |dddd|d< tt |dd|d< t jdi | dS )	r3   r   ZSAMBANOVA_URLz,https://api.sambanova.ai/v1/chat/completionsr   r   ZSAMBANOVA_API_KEYNr!   )r   r   r5   r6   r7   r8   r!   r"   r6     s   

zSambaNovaCloud.__init__rV   rB   c           	   	   C   s   t |tr|g}d|d dg}||| j|| j| j| j| jd}dd | D }d| j	  dd	}t
 }|rE|j| j||d
d}n
|j| j||dd}|jdkratd|j d|j d|S )z
        Performs a post request to the LLM API.

        Args:
            prompt: The prompt to pass into the model.
            stop: list of stop tokens

        Returns:
            A request Response object
        rW   r   rX   )r[   r<   rD   rB   rC   r   r   r   c                 S   r\   r]   r!   r^   r!   r!   r"   rN     r`   z2SambaNovaCloud._handle_request.<locals>.<dictcomp>ra   rb   rc   Tri   Frl   rm   rn   )ro   rJ   rD   rC   r   r   r   rT   r   rp   rr   rs   rt   r   ru   rv   rw   )	r-   rV   rB   r   rx   ry   rj   rz   r{   r!   r!   r"   r|     sB   




zSambaNovaCloud._handle_requestr{   c              
   C   sT   z|  }W n ty } ztd| d|j d}~ww |d d d d }|S )r}   r~   r   Nr   r   r   rZ   )rk   r   rv   rw   r   r!   r!   r"   r     s   z SambaNovaCloud._process_responsec           	      c   s4   zddl }W n ty   tdw ||}| D ]{}|jdkr0td|j d|j dzP|jdkrt|jt	rCt
|j}ntd|j d|j d|drbtd|j d|j dt|d	 dkru|d	 d d
 d }nd}t|d}|V  W q ty } ztd| d|j d}~ww dS )r   r   Nr   r   r   rn   r   r   r   r   rZ   r   r   r   r   )r   r   r   r   r   rv   ru   ry   ro   rJ   rk   r   rP   rQ   r   r   )	r-   r{   r   r   r   ry   rZ   r   r   r!   r!   r"   r     sh   




z'SambaNovaCloud._process_stream_responser   c                 K   r   )  Call out to SambaNovaCloud 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.
        r   r   Fr   Nr!   r   r   r!   r!   r"   r   1  r   zSambaNovaCloud._callc                 k   r   )r   Tr   Nr   r   r!   r!   r"   r   N  r   zSambaNovaCloud._streamr   r   ),r   r   r    r   r   r   rJ   r   r   r   rC   r   r   rD   intr   floatr   r   r   r   dictr#   r   r*   r   r   r.   r   r0   r1   r6   r   r   r   r|   r   r   r   r   r	   r   r   r   r!   r!   r8   r"   r     s   
 @

6<

 
r   )rk   typingr   r   r   r   r   r   r   rr   Z langchain_core.callbacks.managerr	   Z#langchain_core.language_models.llmsr
   Zlangchain_core.outputsr   Zlangchain_core.utilsr   r   Zpydanticr   r   r   r   r   r!   r!   r!   r"   <module>   s    $    