o
    Ag[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__populate_by_name r"   r"   i/var/www/html/development/chatbot/venv/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   SAMBASTUDIO_URLr   SAMBASTUDIO_API_KEYr   r   Nr"   )r   r   _get_sambastudio_urlssuper__init__r.   r3   	__class__r"   r#   r9      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   genericzgeneric/streamUnsupported URL)replacejoinsplit
ValueError)r.   r=   r   
stream_urlr"   r"   r#   r7      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
        Nstop_sequencesr   r>   select_expertmodel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)rP   r   str).0kvr"   r"   r#   
<dictcomp>   s    z2SambaStudio._get_tuning_params.<locals>.<dictcomp>rA   9only openai, generic v1 and generic v2 APIs are supported)r   getlenr   keyspopitemsrE   )r.   rG   _model_kwargs_stop_sequences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"   rS   keyrQ   r"   r"   r#   rV         z/SambaStudio._handle_request.<locals>.<dictcomp>Bearer application/jsonAuthorizationzContent-TyperN   rM   Fzsambaverse-conversation-idN)
message_idrd   re   )conversation_idrf   item0)idrQ   c                 S   rg   rh   r"   ri   r"   r"   r#   rV   2  rk   )r\   paramsrj   rO   rQ   True)instancert   )	instancesrt   rA   rW   Theadersjsonr?      2Sambanova / complete call failed with status code .)
isinstancerR   r`   r   r\   r   get_secret_valuerX   rz   dumpsrE   requestsSessionpostr   r   status_codeRuntimeErrortext)r.   ra   rG   r   rt   messages_dictdatary   r\   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   messagere   rN   r\   rQ   
completionrO   predictionsrA   rW   )rz   	Exceptionr   r   r   rE   r.   r   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 r}   [DONE]errorr   deltare   r   r   3Error getting content chunk raw streamed response: data: rN   resultr\   rQ   stream_tokenzline: rO   	responsesrA   rW   )	sseclientImportErrorr   	SSEClienteventseventr   r   r   r~   rR   rz   loadsrX   rY   r   r   
iter_linesrE   )
r.   r   r   clientr   r   re   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   on_llm_new_tokenr   r.   ra   rG   r   r3   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   ra   rG   r   Fr   Nr"   r   r   r   r   r   r.   ra   rG   r   r3   r   r   r   r"   r"   r#   _call     

zSambaStudio._callrh   NFNN))r   r   r    __doc__r   r   rR   __annotations__r   r   r   r   r   boolr   r   r   r   r$   classmethodr+   propertyr/   r1   r2   r9   r   r7   r   r`   r   r   r   r   r   r   r   r	   r   r   __classcell__r"   r"   r;   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-InstructrJ   Fr   i   rL   gffffff?temperatureNtop_ptop_k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 )r0   rJ   r   rL   r   r   r   r   r   r-   r"   r"   r#   r1     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#   r2     r,   zSambaNovaCloud._llm_typer3   c                    s>   t |dddd|d< tt |dd|d< t jdi | dS )	r4   r   SAMBANOVA_URLz,https://api.sambanova.ai/v1/chat/completionsr   r   SAMBANOVA_API_KEYNr"   )r   r   r8   r9   r:   r;   r"   r#   r9     s   

zSambaNovaCloud.__init__ra   rG   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
        rb   r   rc   )rf   r?   rL   rG   rJ   r   r   r   c                 S   rg   rh   r"   ri   r"   r"   r#   rV     rk   z2SambaNovaCloud._handle_request.<locals>.<dictcomp>rl   rm   rn   Trx   Fr{   r|   r}   )r~   rR   rL   rJ   r   r   r   r\   r   r   r   r   r   r   r   r   r   )	r.   ra   rG   r   r   r   ry   r   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   re   )rz   r   r   r   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   r}   r   r   r   r   re   r   r   r   r   )r   r   r   r   r   r   r   r   r~   rR   rz   r   rX   rY   r   r   )	r.   r   r   r   r   r   re   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   rR   r   r   r   rJ   r   r   rL   intr   floatr   r   r   r   dictr$   r   r+   r   r   r/   r   r1   r2   r9   r   r   r   r   r   r   r   r   r	   r   r   r   r"   r"   r;   r#   r     s   
 @

6<

 
r   )rz   typingr   r   r   r   r   r   r   r    langchain_core.callbacks.managerr	   #langchain_core.language_models.llmsr
   langchain_core.outputsr   langchain_core.utilsr   r   pydanticr   r   r   r   r   r"   r"   r"   r#   <module>   s    $    