a
    bg9                     @   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	< d3ee
e e
e e
e d
d fddZeeef ee ed
dddZeed
dddZeed
dddZeed
dddZeeef eeef ed
dddZeeef ed
dddZeed
dd d!Zeeef eed
d"d#d$Zeeed%d&d'Zd4ee
e e
e ed
d(d)d*Zeed
dd+d,Zeed
d-d.d/Zeed
d0d1d2Z  Z S )5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           	         sp  t    zddl}|j| _W n ty8   tdY n0 t| jtdk r^td| j d|du rtddu rt	
d| j d	 | j}|du rtd
du rt| jtdk rdnd| _t	
d| j d | j}z|j||d W n@ ty, } z&td| d| j d|W Y d}~n
d}~0 0 || _|p@| | _zXi }t| jtdk r|t	
d| j dt ddi}|jjf | j| jd|| _W nX ty } z>td| d| j d| j d| j d| j d|W Y d}~n
d}~0 0 dd g}|d!d" | jjD krRt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   s   g | ]
}|j qS  r   .0fieldr   r   |/var/www/html/cobodadashboardai.evdpl.com/venv/lib/python3.9/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   s   g | ]
}|j qS 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 )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__)
serializedr4   kwargsr   c                 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)r4   updatestr)r5   r:   r4   r;   r   r   r   on_llm_start   s    z#ArgillaCallbackHandler.on_llm_start)tokenr;   r   c                 K   s   dS )z)Do nothing when a new token is generated.Nr   )r5   rA   r;   r   r   r   on_llm_new_token   s    z'ArgillaCallbackHandler.on_llm_new_token)r   r;   r   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 r| j	  dS )z(Log records to Argilla when an LLM ends.r<   Nr=   c                    s    g | ]}d  |j  diqS )r2   r   r   )textstrip)r   Z
generationr   r   r   r       s   z5ArgillaCallbackHandler.on_llm_end.<locals>.<listcomp>recordsr   )
r4   r?   zipgenerationsr0   add_recordspopr   r&   push_to_argilla)r5   r   r;   r4   rJ   r   rF   r   
on_llm_end   s    
z!ArgillaCallbackHandler.on_llm_end)errorr;   r   c                 K   s   dS )z%Do nothing when LLM outputs an error.Nr   r5   rO   r;   r   r   r   on_llm_error   s    z#ArgillaCallbackHandler.on_llm_error)r:   inputsr;   r   c                 K   sH   d|v rD| j t|d p|d t|d tr6|d n|d gi 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)r4   r>   r?   
isinstancelist)r5   r:   rR   r;   r   r   r   on_chain_start   s    
z%ArgillaCallbackHandler.on_chain_start)outputsr;   r   c                    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 ]V\}}t|tr j	j
dd t||D d qf j	j
d	d
|| digd qft|d  jv r jt|d  t|d  jv r jt|d  t jtdk r* j	  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)r4   )r   keyr5   r   r   	<genexpr>  s   z6ArgillaCallbackHandler.on_chain_end.<locals>.<genexpr>r<   r=   Nc                 S   s&   g | ]\}}d ||d   diqS )r2   rD   rC   )rE   )r   r   outputr   r   r   r      s   
z7ArgillaCallbackHandler.on_chain_end.<locals>.<listcomp>rG   r2    rC   r   )anyr?   r4   getr   r   itemsrT   rU   r0   rK   rI   joinrE   rL   r   r&   rM   )r5   rW   r;   r4   Zchain_output_keyZchain_output_valr   rY   r   on_chain_end  s8    
z#ArgillaCallbackHandler.on_chain_endc                 K   s   dS )z+Do nothing when LLM chain outputs an error.Nr   rP   r   r   r   on_chain_error8  s    z%ArgillaCallbackHandler.on_chain_error)r:   	input_strr;   r   c                 K   s   dS )zDo nothing when tool starts.Nr   )r5   r:   rc   r;   r   r   r   on_tool_start<  s    z$ArgillaCallbackHandler.on_tool_start)actionr;   r   c                 K   s   dS )z.Do nothing when agent takes a specific action.Nr   )r5   re   r;   r   r   r   on_agent_actionE  s    z&ArgillaCallbackHandler.on_agent_action)r[   observation_prefix
llm_prefixr;   r   c                 K   s   dS )zDo nothing when tool ends.Nr   )r5   r[   rg   rh   r;   r   r   r   on_tool_endI  s    z"ArgillaCallbackHandler.on_tool_endc                 K   s   dS )z&Do nothing when tool outputs an error.Nr   rP   r   r   r   on_tool_errorS  s    z$ArgillaCallbackHandler.on_tool_error)rD   r;   r   c                 K   s   dS z
Do nothingNr   )r5   rD   r;   r   r   r   on_textW  s    zArgillaCallbackHandler.on_text)finishr;   r   c                 K   s   dS rk   r   )r5   rm   r;   r   r   r   on_agent_finish[  s    z&ArgillaCallbackHandler.on_agent_finish)NNN)NN)!__name__
__module____qualname____doc__r   r?   __annotations__r   r   r   r   r$   r   r   r   r@   rB   r
   rN   BaseExceptionrQ   rV   ra   rb   rd   r   rf   ri   rj   rl   r   rn   __classcell__r   r   r8   r   r      sZ   
+    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   