o
    Zh9                     @   st   d dl Z d dlZd dlmZmZmZmZmZ d dlm	Z	m
Z
 d dlmZ d dlmZ d dlmZ G dd deZdS )	    N)AnyDictListOptionalcast)AgentActionAgentFinish)BaseCallbackHandler)	LLMResult)parsec                       s  e Zd ZU dZdZeed< e dZeed< dZeed< dZ	eed	< 	
	
	
d;dede
e de
e de
e dd
f
 fddZdeeef dee dedd
fddZdededd
fddZdededd
fddZdededd
fddZdeeef d eeef dedd
fd!d"Zd#eeef dedd
fd$d%Zdededd
fd&d'Zdeeef d(ededd
fd)d*Zd+ededefd,d-Z	
	
d<d.ed/e
e d0e
e dedd
f
d1d2Zdededd
fd3d4Zd5ededd
fd6d7Zd8ededd
fd9d:Z  Z S )=ArgillaCallbackHandlera  Callback Handler that logs into Argilla.

    Args:
        dataset_name: name of the `FeedbackDataset` in Argilla. Note that it must
            exist in advance. If you need help on how to create a `FeedbackDataset` in
            Argilla, please visit
            https://docs.argilla.io/en/latest/tutorials_and_integrations/integrations/use_argilla_callback_in_langchain.html.
        workspace_name: name of the workspace in Argilla where the specified
            `FeedbackDataset` lives in. Defaults to `None`, which means that the
            default workspace will be used.
        api_url: URL of the Argilla Server that we want to use, and where the
            `FeedbackDataset` lives in. Defaults to `None`, which means that either
            `ARGILLA_API_URL` environment variable or the default will be used.
        api_key: API Key to connect to the Argilla Server. Defaults to `None`, which
            means that either `ARGILLA_API_KEY` environment variable or the default
            will be used.

    Raises:
        ImportError: if the `argilla` package is not installed.
        ConnectionError: if the connection to Argilla fails.
        FileNotFoundError: if the `FeedbackDataset` retrieval from Argilla fails.

    Examples:
        >>> from langchain_community.llms import OpenAI
        >>> from langchain_community.callbacks import ArgillaCallbackHandler
        >>> argilla_callback = ArgillaCallbackHandler(
        ...     dataset_name="my-dataset",
        ...     workspace_name="my-workspace",
        ...     api_url="http://localhost:6900",
        ...     api_key="argilla.apikey",
        ... )
        >>> llm = OpenAI(
        ...     temperature=0,
        ...     callbacks=[argilla_callback],
        ...     verbose=True,
        ...     openai_api_key="API_KEY_HERE",
        ... )
        >>> llm.generate([
        ...     "What is the best NLP-annotation tool out there? (no bias at all)",
        ... ])
        "Argilla, no doubt about it."
    z%https://github.com/argilla-io/argillaREPO_URLz/issues
ISSUES_URLzphttps://docs.argilla.io/en/latest/tutorials_and_integrations/integrations/use_argilla_callback_in_langchain.htmlBLOG_URLzhttp://localhost:6900DEFAULT_API_URLNdataset_nameworkspace_nameapi_urlapi_keyreturnc           	         sL  t    z
ddl}|j| _W n ty   tdw t| jtdk r-td| j d|du rEtddu rEt	
d| j d	 | j}|du rktd
du rkt| jtdk r[dnd| _t	
d| j d | j}z	|j||d W n ty } ztd| d| j d|d}~ww || _|p| | _z+i }t| jtdk rt	
d| j dt ddi}|jjd*| j| jd|| _W n% ty } ztd| d| j d| j d| j d| j d|d}~ww dd g}|d!d" | jjD krtd#| j d| j d$| d%d&d" | jjD  d'| j d(i | _t	
d)| j d dS )+a)  Initializes the `ArgillaCallbackHandler`.

        Args:
            dataset_name: name of the `FeedbackDataset` in Argilla. Note that it must
                exist in advance. If you need help on how to create a `FeedbackDataset`
                in Argilla, please visit
                https://docs.argilla.io/en/latest/tutorials_and_integrations/integrations/use_argilla_callback_in_langchain.html.
            workspace_name: name of the workspace in Argilla where the specified
                `FeedbackDataset` lives in. Defaults to `None`, which means that the
                default workspace will be used.
            api_url: URL of the Argilla Server that we want to use, and where the
                `FeedbackDataset` lives in. Defaults to `None`, which means that either
                `ARGILLA_API_URL` environment variable or the default will be used.
            api_key: API Key to connect to the Argilla Server. Defaults to `None`, which
                means that either `ARGILLA_API_KEY` environment variable or the default
                will be used.

        Raises:
            ImportError: if the `argilla` package is not installed.
            ConnectionError: if the connection to Argilla fails.
            FileNotFoundError: if the `FeedbackDataset` retrieval from Argilla fails.
        r   NzTo use the Argilla callback manager you need to have the `argilla` Python package installed. Please install it with `pip install argilla`z1.8.0z#The installed `argilla` version is z} but `ArgillaCallbackHandler` requires at least version 1.8.0. Please upgrade `argilla` with `pip install --upgrade argilla`.ZARGILLA_API_URLz[Since `api_url` is None, and the env var `ARGILLA_API_URL` is not set, it will default to `z6`, which is the default API URL in Argilla Quickstart.ZARGILLA_API_KEYz1.11.0zadmin.apikeyzowner.apikeyz[Since `api_key` is None, and the env var `ARGILLA_API_KEY` is not set, it will default to `z6`, which is the default API key in Argilla Quickstart.)r   r   z.Could not connect to Argilla with exception: 'z'.
Please check your `api_key` and `api_url`, and make sure that the Argilla server is up and running. If the problem persists please report it to z as an `integration` issue.1.14.0zYou have Argilla z., but Argilla 1.14.0 or higher is recommended.Zwith_recordsF)nameZ	workspacez@`FeedbackDataset` retrieval from Argilla failed with exception `z+`.
Please check that the dataset with name=z in the workspace=zz exists in advance. If you need help on how to create a `langchain`-compatible `FeedbackDataset` in Argilla, please visit z.. If the problem persists please report it to promptresponsec                 S      g | ]}|j qS  r   .0fieldr   r   e/var/www/html/lang_env/lib/python3.10/site-packages/langchain_community/callbacks/argilla_callback.py
<listcomp>       z3ArgillaCallbackHandler.__init__.<locals>.<listcomp>z`FeedbackDataset` with name=z] had fields that are not supported yet for the`langchain` integration. Supported fields are: z/, and the current `FeedbackDataset` fields are c                 S   r   r   r   r   r   r   r    r!      r"   zl. For more information on how to create a `langchain`-compatible `FeedbackDataset` in Argilla, please visit .zThe `ArgillaCallbackHandler` is currently in beta and is subject to change based on updates to `langchain`. Please report any issues to r   )super__init__Zargilla__version__ARGILLA_VERSIONImportErrorr   osgetenvwarningswarnr   ZDEFAULT_API_KEYinit	ExceptionConnectionErrorr   r   Zget_workspacer   UserWarningZFeedbackDatasetZfrom_argilladatasetFileNotFoundErrorr   fields
ValueErrorprompts)	selfr   r   r   r   Zrge
extra_argsZsupported_fields	__class__r   r    r%   =   s   
	

	zArgillaCallbackHandler.__init__
serializedr5   kwargsc                 K   s$   | j t|d p|d |i dS )z.Save the prompts in memory when an LLM starts.parent_run_idrun_idN)r5   updatestr)r6   r;   r5   r<   r   r   r    on_llm_start   s   $z#ArgillaCallbackHandler.on_llm_starttokenc                 K      dS )z)Do nothing when a new token is generated.Nr   )r6   rB   r<   r   r   r    on_llm_new_token      z'ArgillaCallbackHandler.on_llm_new_tokenr   c                    s   |d rdS | j t|d  }t||jD ]\ }| jj fdd|D d q| j t|d  t| jtdk rB| j	  dS dS )z(Log records to Argilla when an LLM ends.r=   Nr>   c                    s    g | ]}d  |j  diqS )r3   r   r   )textstrip)r   Z
generationr   r   r    r!      s    z5ArgillaCallbackHandler.on_llm_end.<locals>.<listcomp>recordsr   )
r5   r@   zipgenerationsr1   add_recordspopr   r'   push_to_argilla)r6   r   r<   r5   rM   r   rI   r    
on_llm_end   s   
z!ArgillaCallbackHandler.on_llm_enderrorc                 K   rC   )z%Do nothing when LLM outputs an error.Nr   r6   rR   r<   r   r   r    on_llm_error   rE   z#ArgillaCallbackHandler.on_llm_errorinputsc                 K   sL   d|v r$| j t|d p|d t|d tr|d n|d gi dS dS )a  If the key `input` is in `inputs`, then save it in `self.prompts` using
        either the `parent_run_id` or the `run_id` as the key. This is done so that
        we don't log the same input prompt twice, once when the LLM starts and once
        when the chain starts.
        inputr=   r>   N)r5   r?   r@   
isinstancelist)r6   r;   rU   r<   r   r   r    on_chain_start   s   
z%ArgillaCallbackHandler.on_chain_startoutputsc                    s.  t  fddt|d t|d fD sdS  jt|d p.tt jt|d g }| D ]+\}}t|trL j	j
dd t||D d q3 j	j
d	d
|| digd q3t|d  jv rr jt|d  t|d  jv r jt|d  t jtdk r j	  dS dS )zIf either the `parent_run_id` or the `run_id` is in `self.prompts`, then
        log the outputs to Argilla, and pop the run from `self.prompts`. The behavior
        differs if the output is a list or not.
        c                 3   s    | ]}| j v V  qd S )N)r5   )r   keyr6   r   r    	<genexpr>  s
    
z6ArgillaCallbackHandler.on_chain_end.<locals>.<genexpr>r=   r>   Nc                 S   s&   g | ]\}}d ||d   diqS )r3   rG   rF   )rH   )r   r   outputr   r   r    r!     s    
z7ArgillaCallbackHandler.on_chain_end.<locals>.<listcomp>rJ   r3    rF   r   )anyr@   r5   getr   r   itemsrW   rX   r1   rN   rL   joinrH   rO   r   r'   rP   )r6   rZ   r<   r5   Zchain_output_keyZchain_output_valr   r\   r    on_chain_end  s:   
z#ArgillaCallbackHandler.on_chain_endc                 K   rC   )z+Do nothing when LLM chain outputs an error.Nr   rS   r   r   r    on_chain_error8  rE   z%ArgillaCallbackHandler.on_chain_error	input_strc                 K   rC   )zDo nothing when tool starts.Nr   )r6   r;   rf   r<   r   r   r    on_tool_start<  s   z$ArgillaCallbackHandler.on_tool_startactionc                 K   rC   )z.Do nothing when agent takes a specific action.Nr   )r6   rh   r<   r   r   r    on_agent_actionE  rE   z&ArgillaCallbackHandler.on_agent_actionr^   observation_prefix
llm_prefixc                 K   rC   )zDo nothing when tool ends.Nr   )r6   r^   rj   rk   r<   r   r   r    on_tool_endI  s   z"ArgillaCallbackHandler.on_tool_endc                 K   rC   )z&Do nothing when tool outputs an error.Nr   rS   r   r   r    on_tool_errorS  rE   z$ArgillaCallbackHandler.on_tool_errorrG   c                 K   rC   z
Do nothingNr   )r6   rG   r<   r   r   r    on_textW  rE   zArgillaCallbackHandler.on_textfinishc                 K   rC   rn   r   )r6   rp   r<   r   r   r    on_agent_finish[  rE   z&ArgillaCallbackHandler.on_agent_finish)NNN)NN)!__name__
__module____qualname____doc__r   r@   __annotations__r   r   r   r   r%   r   r   r   rA   rD   r
   rQ   BaseExceptionrT   rY   rd   re   rg   r   ri   rl   rm   ro   r   rq   __classcell__r   r   r9   r    r      s   
 + 




2

	

r   )r)   r+   typingr   r   r   r   r   Zlangchain_core.agentsr   r   Zlangchain_core.callbacksr	   Zlangchain_core.outputsr
   Zpackaging.versionr   r   r   r   r   r    <module>   s    