
    e<U                        d Z ddl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mZmZ ddlZdd	lmZ dd
lmZmZ ddlm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$m%Z% e G d d                      Z& G d de"          Z'dS )z
The interface module provides an even higher-level API for interacting
with a list of `ChatMessage` objects compared to the `ChatFeed`
through a frontend input UI.
    )annotations)	dataclass)partial)BytesIO)AnyCallableClassVarDictListN   )CDN_DIST)RowTabs)	ImageBase)Viewable)Widget)Button)	FileInput	TextInput   )CallbackStateChatFeed)ChatMessage_FileInputMessagec                  P    e Zd ZU dZded<   ded<   ded<   ded<   ded	<   d
ed<   dS )_ChatButtonDataae  
    A dataclass to hold the metadata and data related to the
    chat buttons.

    Parameters
    ----------
    index : int
        The index of the button.
    name : str
        The name of the button.
    icon : str
        The icon to display.
    objects : List
        The objects to display.
    buttons : List
        The buttons to display.
    intindexstrnameiconr   objectsbuttonsr   callbackN)__name__
__module____qualname____doc____annotations__     4lib/python3.11/site-packages/panel/chat/interface.pyr   r      sW          $ JJJIIIIIIMMMMMMr+   r   c                  8    e Zd ZU dZ ej        d          Z ej        ee	e
efd          Z ej        dd          Z ej        dd	          Z ej        dd
          Z ej        dd          Z ej        dd          Z ej        dd          Z ej        dd          Z ej        dd          Z ej        eefdd          Z ej        i d          Z ej        i dd          Z ej        ed          Z ej        eefd          Z  ej        i d          Z! ej        i d          Z"e# dgZ$de%d<    fdZ&dVd"Z' ej(        d#d$          d%             Z) ej(        d&d'd$          d(             Z*	 	 	 dWdXd/Z+	 	 dYdZd6Z,	 	 dYd[d8Z-d\d:Z.d]d>Z/d? Z0	 	 dYdZd@Z1	 	 dYdZdAZ2	 	 dYdZdBZ3e4d^dD            Z5e4d\dE            Z6e6j7        d_dG            Z6	 	 	 d`da fdRZ8 ej(        dSd$          dT             Z9 fdUZ: xZ;S )bChatInterfacear  
    High level widget that contains the chat log and the chat input.

    Reference: https://panel.holoviz.org/reference/chat/ChatInterface.html

    :Example:

    >>> async def repeat_contents(contents, user, instance):
    >>>     yield contents

    >>> chat_interface = ChatInterface(
        callback=repeat_contents, widgets=[TextInput(), FileInput()]
    )
    z
        The widget types to automatically send when the user presses enter
        or clicks away from the widget. If not provided, defaults to
        `[TextInput]`.)docz
        The avatar to use for the user. Can be a single character text, an emoji,
        or anything supported by `pn.pane.Image`. If not set, uses the
        first character of the name.)class_r/   Tzl
        Whether to reset the widget's value after sending a message;
        has no effect for `TextInput`.)defaultr/   z)
        Whether to show the send button.z
        Whether to show the stop button temporarily replacing the send button during
        callback; has no effect if `callback` is not async.z*
        Whether to show the rerun button.z)
        Whether to show the undo button.z*
        Whether to show the clear button.Nz)
        Whether to show the button name.Userz(
        Name of the ChatInterface user.FzZ
        Widgets to use for the input. If not provided, defaults to
        `[TextInput]`.)r0   
allow_refsr/   a"  
        Allows addition of functionality or customization of buttons
        by supplying a mapping from the button name to a dictionary
        containing the `icon`, `callback`, and/or `post_callback` keys.
        If the button names correspond to default buttons
        (send, rerun, undo, clear), the default icon can be
        updated and if a `callback` key value pair is provided,
        the specified callback functionality runs before the existing one.
        For button names that don't match existing ones,
        new buttons are created and must include a `callback` or `post_callback` key.
        The provided callbacks should have a signature that accepts
        two positional arguments: instance (the ChatInterface instance)
        and event (the button click event).
        z
        The input widgets.)r1   r3   r/   z
        The input message row that wraps the input layout (Tabs / Row)
        to easily swap between Tabs and Rows, depending on
        number of widgets.z:
        The input layout that contains the input widgets.z2
        Metadata and data related to the buttons.z
        The rendered buttons.zcss/chat_interface.csszClassVar[List[str]]_stylesheetsc                   |                     d          }|t          d          g|d<   nt          |t                    s|g|d<   |                    dd           } t                      j        |i | t          dg| j                  | _	        | 
                                 |                                  ||| _        | j        j                            | j        j        | j	        gz   dg           d S )	NwidgetszSend a message)placeholderactivezchat-interface-input-container)css_classesstylesheetszchat-interface)r"   r9   )getr   
isinstancelistpopsuper__init__r   r4   _input_container_update_input_width_init_widgetsr8   _cardparamupdater"   )selfr"   paramsr6   r8   	__class__s        r,   r@   zChatInterface.__init__   s   **Y''?!*7G!H!H!H IF9GT** 	*!(	F9Hd++',V,,, #9:)!
 !
 !
 	  """ DK
J&$*?)@@)* 	  	
 	
 	
 	
 	
r+   objr   c           	     n    dD ]1}t          ||t          | |                      | j        |fi ||i 2dS )zg
        Link the disabled and loading attributes of the chat box to the
        given object.
        )disabledloadingN)setattrgetattrlink)rG   rJ   attrs      r,   _link_disabled_loadingz$ChatInterface._link_disabled_loading   sZ    
 , 	+ 	+DCwtT22333DIc**dD\****	+ 	+r+   width)watchc                J    | j         | j        du p
| j        dk    | _         dS dS )z)
        Update the input width.
        Ni  )show_button_namerS   rG   s    r,   rB   z!ChatInterface._update_input_width   s6    
  ($(J$$6$K$*:KD!!! )(r+   r6   button_propertiesc                	   d| j         dd| j        dd| j        dd| j        dd| j        dd}t          | j                  dk    | _        i || j        }t          |	                                          D ]\  }\  }}|
                                }|                    d	          }|                    d
          }|                    |          pi }|r0|d         }	||! |                     |||          |	          n|	}nB|"|  |                     |          |          }n|||}n||t          d|d          |                    d          p|                    d          }
t          |||
g g |          | j        |<   | j        }t#          | j        t$                    r| j        g}i | _        g }|D ]o}|j        p|j        j        }t#          |t.                    r
 |            }| j                            |          |ur|| j        |<   |                    |           p| j        }|d|v sd|v rd}nd|v rd}t5          |dg| j        d          }| j        	                                D ]4\  }}t#          |t9          | j                            pt/          |          t<          u }|r?||v r;t?          | j        d         j         |           }|j!        "                    |d           |j!        #                    ddg           i | _$        | j        %                                D ]"}|j        }	 |dk    r| j!        d|          nd}n# tL          $ r d}Y nw xY w| j!        j'        (                                }tS          |j(        *                    |j        +                                d           |j,        d|j(        *                    d!d"          d#d$d%|&          }|dk    r| -                    |           t?          |j         |           }|.                    |           || j$        |<   |j/                            |           $ta          |gtc          | j$        %                                          R dd'g| j        d(d)}|                    ||f           6t          | j                  d*k    r|d         }|g| j2        _3        || _4        dS )+zk
        Initialize the input widgets.

        Returns
        -------
        The input widgets.
        send)r!   _default_callbackzplayer-stoprepeatz
arrow-backtrash)rZ   stoprerunundoclearr   r$   post_callbackr[   N)r$   rb   r    )rb   z%A 'callback' key is required for the z buttonr!   )r   r    r!   r"   r#   r$   bothscale_heightstretch_widthheightzchat-interface-input-tabsT)sizing_moder9   r:   dynamicvaluezchat-interface-input-widget)rg   r9   r^   show_F Z   -   2   )r      r   r   center)r    r!   rg   	max_width
max_heightmarginalignvisiblezchat-interface-input-rowstart)rg   r9   r:   rt   r   )5_click_send_click_stop_click_rerun_click_undo_click_clearlenrX   _allow_revert	enumerateitemslowerr;   _wrap_callbacks
ValueErrorr   _button_datar6   r<   r   _widgetsr    rI   r%   typeappendrg   r   r4   tupleauto_send_typesr   r   r$   rE   rT   rF   _buttonsvaluesKeyErrorrV   rxr   wheretitler!   rR   on_clickr#   r   r=   rA   r"   _input_layout)rG   default_button_propertiesrX   r   r    
propertiesr$   rb   default_propertiesdefault_callbackr!   r6   new_widgetswidgetkeyrg   input_layout	auto_sendbutton_dataactionru   	show_exprbuttonmessage_rows                           r,   rC   zChatInterface._init_widgets   s    $$:JKK*AQRR&T=NOO)@PQQ%D<MNN%
 %
! !!788A=S8SD<RS)23D3J3J3L3L)M)M 	 	%E%D*::<<D!~~j11H&NN?;;M!:!>!>t!D!D!J! Z#56I#J   +}/HD((!)&3! )   '	( ( (
 O_  %-*CL4//m/LLXVV!m&?(!m&; !X!X!X!XYYY>>&))K-?-C-CF-K-KD&5!' ' 'Dd## ,dlF++ 	%|nG 	+ 	+F+:!1!:C&$'' "}  %%V33%+c"""6***&"$$+(E(E-[(("#45)	
 
 
 !M//11 3	5 3	5LD& 65)=#>#>?? *V	)   6V{22"4#4V#<#EtLL""8W555L+:;     
 DM#07799 3 3$)#>D>N>Ndj)9)9)9::TYGG # # #"GGG# J7::<<	"++K,<,B,B,D,DbII$) /'l00R88!'"#	 	 	 V##//777";#7>>)))(.f%#**62222dm**,,--  ,78 -  K { 34444 t}""'?L)5%)s   M%%M43M4rk   r$   Callable | Nonerb   r    r   c                    dfd}|S )zR
        Wrap the callback and post callback around the default callback.
        r   r   c                     d fd}|S )Neventparam.parameterized.Eventc                    dk    r| j         j        sd S (	 d| _         | |           d| _        n# d| _        w xY w | |           )	 d| _         | |           d| _        d S # d| _        w xY wd S )NrZ   TF)active_widgetri   rL   )rG   r   r$   r   r    rb   s     r,   wrapperz@ChatInterface._wrap_callbacks.<locals>.decorate.<locals>.wrapperL  s    6>>$*<*B>F'.(, u---(-----  u--- ,.(,%dE222(----- -,s   4 	=A+ +	A4)r   r   r*   )r   r   r$   r    rb   s   ` r,   decoratez/ChatInterface._wrap_callbacks.<locals>.decorateK  s8    . . . . . . . . .( Nr+   )r   r   r*   )rG   r$   rb   r    r   s    ``` r,   r   zChatInterface._wrap_callbacksB  s4    	 	 	 	 	 	 	 	, r+   r    param.parameterized.Event | Noneinstance'ChatInterface' | NonereturnNonec                   | j         rdS | j        }|j        }|rt          |t                    rt          ||j        |j                  }t          |          t          u s| j
        rEddi}t          |d          rd|d<   	 |j                            |           n# t          $ r Y nw xY wndS |                                  |                     || j        | j        d           dS )z=
        Send the input when the user presses Enter.
        N)contents	mime_type	file_nameri   rk   value_inputT)ri   useravatarrespond)rL   r   ri   r<   r   r   r   filenamer   r   reset_on_sendhasattrrE   rF   r   _reset_button_datarZ   r   r   )rG   r   r   r   ri   updatess         r,   rw   zChatInterface._click_sendc  s#    = 	F*# 	-33 )"+5+4   M""i//43E/"B-=-88 0-/GM*!'..w7777!   D 0 F!!!		DIdk4	PPPPPs   B 
B*)B*boolc                *    |                                  S )zL
        Cancel the callback when the user presses the Stop button.
        )r^   )rG   r   r   s      r,   rx   zChatInterface._click_stop  s     yy{{r+   r   c                z    | j         ddd         }t          |d          D ]\  }}|j        | j        k    r|c S dS )z9
        Get the index of the last user message.
        Nr   r   )r"   r~   r   )rG   messagesr   messages       r,   _get_last_user_entry_indexz(ChatInterface._get_last_user_entry_index  sU     <"%'!44 	 	NE7|ty(( )qr+   r   r   r8   c                    |j         D ][}|r|j        rdddd}n/d| j        r|j                                        nd| j        rdndd}|j                            |           \dS )	zk
        Toggle the button's icon and name to indicate
        whether the action can be reverted.
        warningRevertrl   )button_typer    rS   r1   rk   rm   N)r#   r"   rV   r    r   rE   rF   )rG   r   r8   r   button_updates        r,   _toggle_revertzChatInterface._toggle_revert  s    
 ") 	/ 	/F +- #,$! ! $-8<8MUK,22444SU#'#8@RRb! !
 L....	/ 	/r+   c                    | j                                         D ]1}|j                                         |                     |d           2dS )zY
        Clears all the objects in the button data
        to prevent reverting.
        FN)r   r   r"   ra   r   )rG   r   s     r,   r   z ChatInterface._reset_button_data  sZ    
  ,3355 	4 	4K%%'''U3333	4 	4r+   c                    |                                  }|                     |          }|sdS |                     |d         d           dS )z|
        Upon clicking the rerun button, rerun the last user message,
        which can trigger the callback again.
        Nr   T)ri   r   )r   r`   rZ   )rG   r   r   countr   s        r,   ry   zChatInterface._click_rerun  sS     //1199U## 	F		T	22222r+   c                X   | j         d         }|j        }|sj|                                  |                                 }|                     |          |_        | j        r|                     |d           dS g |_        dS |                     |           |                                  dS )z
        Upon clicking the undo button, undo (remove) messages
        up to the last user message. If the button is clicked
        again without performing any other actions, revert the undo.
        r`   TN)r   r"   r   r   r`   r}   r   extend)rG   r   r   	undo_dataundo_objectsr   s         r,   rz   zChatInterface._click_undo  s     %f-	 ( 
	&##%%%3355E $		% 0 0I! '##It44444$&	!!!KK%%%##%%%%%r+   c                6   | j         d         }|j        }|sU|                                  |                                 |_        | j        r|                     |d           dS g |_        dS |                                | dd<   |                                  dS )z
        Upon clicking the clear button, clear the chat log.
        If the button is clicked again without performing any
        other actions, revert the clear.
        ra   TN)r   r"   r   ra   r}   r   copy)rG   r   r   
clear_dataclear_objectss        r,   r{   zChatInterface._click_clear  s     &w/
"* 		&##%%%!%J! (##J55555%'
"""#((**DG##%%%%%r+   r   c                    t          | j        t                    r| j        | j                 j        d         S | j        j        d         S )zj
        The currently active widget.

        Returns
        -------
        The active widget.
        r   )r<   r   r   r8   r"   rW   s    r,   r   zChatInterface.active_widget  sB     d($// 	>%dk2:1==!)!,,r+   c                R    t          | j        t                    r| j        j        S dS )z
        The currently active input widget tab index;
        -1 if there is only one widget available
        which is not in a tab.

        Returns
        -------
        The active input widget tab index.
        r   r<   r   r   r8   rW   s    r,   r8   zChatInterface.active  s*     d($// 	-%,,rr+   r   c                V    t          | j        t                    r|| j        _        dS dS )z
        Set the active input widget tab index.

        Arguments
        ---------
        index : int
            The active index to set.
        Nr   )rG   r   s     r,   r8   zChatInterface.active  s4     d($// 	.(-D%%%	. 	.r+   	assistantr   List[ChatMessage]
role_names!Dict[str, str | List[str]] | Nonedefault_role
str | Nonecustom_serializerr   List[Dict[str, Any]]c                r    || j         g| j        gd}t                                          ||||          S )a  
        Exports the chat log for use with transformers.

        Arguments
        ---------
        messages : list(ChatMessage)
            A list of ChatMessage objects to serialize.
        role_names : dict(str, str | list(str)) | None
            A dictionary mapping the role to the ChatMessage's user name.
            Defaults to `{"user": [self.user], "assistant": [self.callback_user]}`
            if not set. The keys and values are case insensitive as the strings
            will all be lowercased. The values can be a string or a list of strings,
            e.g. `{"user": "user", "assistant": ["executor", "langchain"]}`.
        default_role : str
            The default role to use if the user name is not found in role_names.
            If this is set to None, raises a ValueError if the user name is not found.
        custom_serializer : callable
            A custom function to format the ChatMessage's object. The function must
            accept one positional argument, the ChatMessage object, and return a string.
            If not provided, uses the serialize method on ChatMessage.

        Returns
        -------
        A list of dictionaries with a role and content keys.
        N)r   r   )r   callback_userr?   _serialize_for_transformers)rG   r   r   r   r   rI   s        r,   r   z)ChatInterface._serialize_for_transformers  sI    @ "01 J ww228ZWhiiir+   _callback_statec                  K   t           j        t           j        f}| j        r	| j        |vr^t
          j                            |           5  d| j        d         _	        d| j        d         _	        d d d            d S # 1 swxY w Y   d S t
          j                            |           5  d| j        d         _	        d| j        d         _	        d d d            d S # 1 swxY w Y   d S )NTrZ   Fr^   )
r   RUNNING
GENERATING	show_stopr   rE   parameterizedbatch_call_watchersr   ru   )rG   busy_statess     r,   _update_input_disabledz$ChatInterface._update_input_disabledF  sa     $,m.FG~ 	5!5[!H!H$88>> 6 604f%-05f%-6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 $88>> 5 505f%-04f%-5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5s$   
%A<<B B (%CC!Cc                   K   t                                                       d{V  |                                  d{V  dS )zF
        Events to always execute after the callback is done.
        N)r?   _cleanup_responser   )rG   rI   s    r,   r   zChatInterface._cleanup_responseR  s[       gg'')))))))))))+++++++++++r+   )rJ   r   )NNrk   )r$   r   rb   r   r    r   )NN)r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   )r   r   r8   r   )r   r   )r   r   r   r   )Nr   N)
r   r   r   r   r   r   r   r   r   r   )<r%   r&   r'   r(   rE   r   r   ClassSelectorr   r   bytesr   r   Booleanr   	show_sendr   
show_rerun	show_undo
show_clearrV   Stringr   r   r=   r6   r
   rX   r   r   rA   r   r   r   r   r   r4   r)   r@   rR   dependsrB   rC   r   rw   rx   r   r   r   ry   rz   r{   propertyr   r8   setterr   r   r   __classcell__)rI   s   @r,   r.   r.   9   s          !ej &   O
 !U gui(H O( ) ) )F
 "EM$ 5* + + +M d 1, - - -I d 1? @ @ @I t 2- . . .J d 1, - - -I t 2- . . .J %u}T 8, - - - 5< -+ , , ,D "e!&$E P   G #
2 4    uz" =   H +u*# <   
 (E'T{ A= > > >M 5:b /5 6 6 6L uz" +! " " "H -5)L)L)L(MLMMMM
 
 
 
 
,+ + + + U]7$'''L L ('L U]91>>>E* E* ?>E*R )--1	    F 37+/"Q "Q "Q "Q "QL 37+/       / / / /(4 4 4 37+/3 3 3 3 3" 37+/& & & & &4 37+/& & & & &. 
- 
- 
- X
-    X ]
. 
. 
. ]
. 9=#.&*%j %j %j %j %j %j %jN U]$D111	5 	5 21	5, , , , , , , , ,r+   r.   )(r(   
__future__r   dataclassesr   	functoolsr   ior   typingr   r   r	   r
   r   rE   io.resourcesr   layoutr   r   
pane.imager   viewabler   widgets.baser   widgets.buttonr   widgets.inputr   r   feedr   r   r   r   r   r   r.   r*   r+   r,   <module>r     s    # " " " " " ! ! ! ! ! !                           # # # # # #         " " " " " "       ! ! ! ! ! ! # # # # # # 0 0 0 0 0 0 0 0 ) ) ) ) ) ) ) ) 3 3 3 3 3 3 3 3        6^, ^, ^, ^, ^,H ^, ^, ^, ^, ^,r+   