o
    Zh:                     @   s   d dl Z d dlZd dlmZmZ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 d dlmZmZmZ d dlmZmZmZ d dlmZmZ e eZed	d
ddG dd deZdS )    N)AnyDictIteratorListMappingOptionalUnion)
deprecated)CallbackManagerForLLMRun)BaseLLM)
GenerationGenerationChunk	LLMResult)convert_to_secret_strget_from_dict_or_envpre_init)
ConfigDict	SecretStrz0.0.18z1.0zlangchain_ibm.WatsonxLLM)ZsinceZremovalZalternative_importc                   @   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 ed< 	 dZe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 ed< 	 dZee ed< 	 dZee ed< 	 dZeeef ed< 	 dZeed< 	 dZeed< eddZedefddZede eef fddZ!e"de de fddZ#ede$eef fddZ%edefd d!Z&e'	d8d"ee(e eef   de eef fd#d$Z)d8d%ee(e  de eef fd&d'Z*d"e(e de+fd(d)Z,d*e eef de-fd+d,Z.		d9d-ed%ee(e  d.ee/ d/edef
d0d1Z0			d:d2e(e d%ee(e  d.ee/ d3ee d/ede+fd4d5Z1		d9d-ed%ee(e  d.ee/ d/ede2e- f
d6d7Z3dS );
WatsonxLLMa-  
    IBM watsonx.ai large language models.

    To use, you should have ``ibm_watsonx_ai`` python package installed,
    and the environment variable ``WATSONX_APIKEY`` set with your API key, or pass
    it as a named parameter to the constructor.


    Example:
        .. code-block:: python

            from ibm_watsonx_ai.metanames import GenTextParamsMetaNames
            parameters = {
                GenTextParamsMetaNames.DECODING_METHOD: "sample",
                GenTextParamsMetaNames.MAX_NEW_TOKENS: 100,
                GenTextParamsMetaNames.MIN_NEW_TOKENS: 1,
                GenTextParamsMetaNames.TEMPERATURE: 0.5,
                GenTextParamsMetaNames.TOP_K: 50,
                GenTextParamsMetaNames.TOP_P: 1,
            }

            from langchain_community.llms import WatsonxLLM
            watsonx_llm = WatsonxLLM(
                model_id="google/flan-ul2",
                url="https://us-south.ml.cloud.ibm.com",
                apikey="*****",
                project_id="*****",
                params=parameters,
            )
     model_iddeployment_id
project_idspace_idNurlapikeytokenpasswordusernameinstance_idversionparamsverifyF	streamingwatsonx_modelZforbid)extrareturnc                 C      dS )NF )clsr(   r(   Z/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/llms/watsonxllm.pyis_lc_serializablef   s   zWatsonxLLM.is_lc_serializablec                 C   s   dddddddS )NWATSONX_URLWATSONX_APIKEYWATSONX_TOKENWATSONX_PASSWORDWATSONX_USERNAMEWATSONX_INSTANCE_ID)r   r   r   r   r   r   r(   selfr(   r(   r*   
lc_secretsj   s   zWatsonxLLM.lc_secretsvaluesc              	   C   sT  t t|dd|d< d|dd v rt t|dd|d< n|d s>dtjvr>|d	 s>d
tjvr>|d s>dtjvr>td|d sGdtjv rRt t|dd|d< n;|d	 s[d
tjv rpt t|d	d
|d	< t t|dd|d< n|d sydtjv rt t|dd|d< t t|dd|d< |d rdtjvrt t|dd|d< z}ddlm} |d r|d  nd|d r|d  nd|d r|d  nd|d	 r|d	  nd|d r|d  nd|d r|d  nd|d r|d  ndd}dd |	 D }||d |d ||d |d |d |d d}||d< W |S  t
y)   t
dw ) zCValidate that credentials and python package exists in environment.r   r,   zcloud.ibm.comr   r   r-   r   r.   r   r/   zDid not find 'token', 'password' or 'apikey', please add an environment variable `WATSONX_TOKEN`, 'WATSONX_PASSWORD' or 'WATSONX_APIKEY' which contains it, or pass 'token', 'password' or 'apikey' as a named parameter.r   r0   r   r1   r   )ModelInferenceNr    )r   r   r   r   r   r   r    c                 S   s   i | ]\}}|d ur||qS Nr(   ).0keyvaluer(   r(   r*   
<dictcomp>   s    z3WatsonxLLM.validate_environment.<locals>.<dictcomp>r   r   r!   r   r   r"   )r   r   credentialsr!   r   r   r"   r$   zdCould not import ibm_watsonx_ai python package. Please install it with `pip install ibm_watsonx_ai`.)r   r   getZget_secret_valueosenviron
ValueErrorZ ibm_watsonx_ai.foundation_modelsr6   itemsImportError)r)   r5   r6   r<   Zcredentials_without_none_valuer$   r(   r(   r*   validate_environmentu   s   














	zWatsonxLLM.validate_environmentc                 C   s   | j | j| j| j| jdS )zGet the identifying parameters.r   r   r!   r   r   rD   r2   r(   r(   r*   _identifying_params   s   zWatsonxLLM._identifying_paramsc                 C   r'   )zReturn type of llm.zIBM watsonx.air(   r2   r(   r(   r*   	_llm_type   s   zWatsonxLLM._llm_typeresponsec                 C   s~   | d u r	dddS d}d}dt dtt tf dtfdd}| D ]}|d}|r9||d	|d 7 }||d
|d 7 }q||dS )Nr   )generated_token_countinput_token_countr9   resultr&   c                 S   s   | | dpdS )Nr   )r=   )r9   rJ   r(   r(   r*   get_count_value   s   z8WatsonxLLM._extract_token_usage.<locals>.get_count_valueresultsrI   rH   )strr   r   intr=   )rG   rI   rH   rK   resrL   r(   r(   r*   _extract_token_usage   s    

zWatsonxLLM._extract_token_usagestopc                 C   s(   | j ri | j ni }|d ur||d< |S )NZstop_sequences)r!   )r3   rQ   r!   r(   r(   r*   _get_chat_params  s   zWatsonxLLM._get_chat_paramsc           	      C   sv   g }|D ]#}| d}|r'|d  d}t|d  dd|id}||g q| |}|| j| jd}t||dS )	z2Create the LLMResult from the choices and prompts.rL   r   stop_reasongenerated_textfinish_reasontextgeneration_info)Ztoken_usager   r   generations
llm_output)r=   r   appendrP   r   r   r   )	r3   rG   rZ   rO   rL   rU   genZfinal_token_usager[   r(   r(   r*   _create_llm_result  s"   

zWatsonxLLM._create_llm_resultstream_responsec                 C   sL   |d s	t ddS t |d d d t|d d dd| j| jdd	d
S )z0Convert a stream response to a generation chunk.rL   r   rW   r   rT   rS   N)r   r   )rU   r[   rV   )r   dictr=   r   r   )r3   r_   r(   r(   r*   $_stream_response_to_generation_chunk  s   
z/WatsonxLLM._stream_response_to_generation_chunkpromptrun_managerkwargsc                 K   s*   | j d|g||d|}|jd d jS )a  Call the IBM watsonx.ai inference endpoint.
        Args:
            prompt: The prompt to pass into the model.
            stop: Optional list of stop words to use when generating.
            run_manager: Optional callback manager.
        Returns:
            The string generated by the model.
        Example:
            .. code-block:: python

                response = watsonx_llm.invoke("What is a molecule")
        )promptsrQ   rd   r   Nr(   )	_generaterZ   rW   )r3   rc   rQ   rd   re   rJ   r(   r(   r*   _call1  s   zWatsonxLLM._callrf   streamc                 K   s   | j |d}|dur|n| j}|rbt|dkrtd| tdd}| j|d f||d|}	|	D ]}
|du r<|
}q3||
7 }q3|dusGJ t|jtr[|j	d	}t
|gg|d
S t
|ggdS | jj||d}| |S )a  Call the IBM watsonx.ai inference endpoint which then generate the response.
        Args:
            prompts: List of strings (prompts) to pass into the model.
            stop: Optional list of stop words to use when generating.
            run_manager: Optional callback manager.
        Returns:
            The full LLMResult output.
        Example:
            .. code-block:: python

                response = watsonx_llm.generate(["What is a molecule"])
        rQ   N   z6WatsonxLLM currently only supports single prompt, got r   r`   r   )rQ   rd   r[   rY   )rZ   )rc   r!   )rR   r#   lenr@   r   _stream
isinstancerX   ra   popr   r$   generater^   )r3   rf   rQ   rd   ri   re   r!   Zshould_streamZ
generationZstream_iterchunkr[   rG   r(   r(   r*   rg   I  s4   


zWatsonxLLM._generatec                 k   sN    | j |d}| jj|d|dD ]}| |}|r!|j|j|d |V  qdS )a4  Call the IBM watsonx.ai inference endpoint which then streams the response.
        Args:
            prompt: The prompt to pass into the model.
            stop: Optional list of stop words to use when generating.
            run_manager: Optional callback manager.
        Returns:
            The iterator which yields generation chunks.
        Example:
            .. code-block:: python

                response = watsonx_llm.stream("What is a molecule")
                for chunk in response:
                    print(chunk, end='')  # noqa: T201
        rj   T)rc   Zraw_responser!   )rq   N)rR   r$   Zgenerate_text_streamrb   Zon_llm_new_tokenrW   )r3   rc   rQ   rd   re   r!   Zstream_resprq   r(   r(   r*   rm   v  s   

zWatsonxLLM._streamr7   )NN)NNN)4__name__
__module____qualname____doc__r   rM   __annotations__r   r   r   r   r   r   r   r   r   r   r   r    r!   ra   r"   r   boolr#   r$   r   r   Zmodel_configclassmethodr+   propertyr   r4   r   rC   r   rE   rF   staticmethodr   rP   rR   r   r^   r   rb   r
   rh   rg   r   rm   r(   r(   r(   r*   r      s   
 
e

$





0
r   )loggingr>   typingr   r   r   r   r   r   r   Zlangchain_core._api.deprecationr	   Zlangchain_core.callbacksr
   Z#langchain_core.language_models.llmsr   Zlangchain_core.outputsr   r   r   Zlangchain_core.utilsr   r   r   Zpydanticr   r   	getLoggerrr   loggerr   r(   r(   r(   r*   <module>   s    $
