
    3fi2                        d dl Z d dlZd dlZd dlmZmZ d dlmZmZm	Z	m
Z
mZmZmZmZmZ d dlmZmZ d dl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 m!Z!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+ d dlmZm,Z,m-Z- 	 d dl&m.Z.  ej`                  e1      Z2 G d de      Z3de4dedefdZ5 G d de3      Z6ee'e%e4f   Z7da8 G d de      Z9y# e$ r	 d dlmZ Y w xY w# e$ r  e/de/fi       Z.Y kw xY w)    N)ABCabstractmethod)	AnyAsyncGeneratorDict	GeneratorListOptionalSequenceUnioncast)
deprecatedwarn_deprecated)ColumnIntegerTextdeleteselect)declarative_base)BaseChatMessageHistory)BaseMessagemessage_to_dictmessages_from_dict)create_engine)Engine)AsyncEngineAsyncSessioncreate_async_engine)Session)r   scoped_sessionsessionmaker)async_sessionmakerr"   c                   ^    e Zd ZdZededefd       Zedededefd       Z	edefd       Z
y	)
BaseMessageConverterz,Convert BaseMessage to the SQLAlchemy model.sql_messagereturnc                     t         )z5Convert a SQLAlchemy model to a BaseMessage instance.NotImplementedErrorselfr%   s     l/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langchain_community/chat_message_histories/sql.pyfrom_sql_modelz#BaseMessageConverter.from_sql_model:   
     "!    message
session_idc                     t         )z5Convert a BaseMessage instance to a SQLAlchemy model.r(   r+   r0   r1   s      r,   to_sql_modelz!BaseMessageConverter.to_sql_model?   r.   r/   c                     t         )zGet the SQLAlchemy model class.r(   r+   s    r,   get_sql_model_classz(BaseMessageConverter.get_sql_model_classD   r.   r/   N)__name__
__module____qualname____doc__r   r   r   r-   strr4   r7    r/   r,   r$   r$   7   si    6"# "+ " " "K "S "S " " "S " "r/   r$   
table_nameDynamicBaser&   c                 "      G  fdd|      }|S )z
    Create a message model for a given table name.

    Args:
        table_name: The name of the table to use.
        DynamicBase: The base class to use for the model.

    Returns:
        The model class.

    c                   H    e Zd ZW  Z eed      Z ee      Z ee      Z	y)%create_message_model.<locals>.MessageT)primary_keyN)
r8   r9   r:   __tablename__r   r   idr   r1   r0   )r>   s   r,   MessagerB   X   s&    "G.D\
,r/   rF   r=   )r>   r?   rF   s   `  r,   create_message_modelrG   J   s    +  Nr/   c                   L    e Zd ZdZdefdZdedefdZdededefd	Z	defd
Z
y)DefaultMessageConverterz8The default message converter for SQLChatMessageHistory.r>   c                 6    t        |t                     | _        y N)rG   r   model_class)r+   r>   s     r,   __init__z DefaultMessageConverter.__init__d   s    /
<L<NOr/   r%   r&   c                 Z    t        t        j                  |j                        g      d   S )Nr   )r   jsonloadsr0   r*   s     r,   r-   z&DefaultMessageConverter.from_sql_modelg   s$    !4::k.A.A#B"CDQGGr/   r0   r1   c                 `    | j                  |t        j                  t        |                  S )N)r1   r0   )rL   rO   dumpsr   r3   s      r,   r4   z$DefaultMessageConverter.to_sql_modelj   s-    !4::og6N+O   
 	
r/   c                     | j                   S rK   )rL   r6   s    r,   r7   z+DefaultMessageConverter.get_sql_model_classo   s    r/   N)r8   r9   r:   r;   r<   rM   r   r   r-   r4   r7   r=   r/   r,   rI   rI   a   sO    BP3 PH# H+ H
K 
S 
S 

 S  r/   rI   Fc                      e Zd ZdZe eddd      deeef   fd              Z		 	 	 	 	 	 	 d!d	e
d
ee
   de
de
dee   dedef   deee
ef      dee   fdZd"dZd"dZedee   fd       Zdee   fdZdee   fdZdeddfdZdeddfdZdee   ddfdZdee   ddfdZd"dZd"dZe jB                  de"e#ddf   fd       Z$e jJ                  de&e'df   fd        Z(y)#SQLChatMessageHistorya%  Chat message history stored in an SQL database.

    Example:
        .. code-block:: python

            from langchain_core.messages import HumanMessage

            from langchain_community.chat_message_histories import SQLChatMessageHistory

            # create sync sql message history by connection_string
            message_history = SQLChatMessageHistory(
                session_id='foo', connection_string='sqlite///:memory.db'
            )
            message_history.add_message(HumanMessage("hello"))
            message_history.message

            # create async sql message history using aiosqlite
            # from sqlalchemy.ext.asyncio import create_async_engine
            #
            # async_engine = create_async_engine("sqlite+aiosqlite:///memory.db")
            # async_message_history = SQLChatMessageHistory(
            #     session_id='foo', connection=async_engine,
            # )
            # await async_message_history.aadd_message(HumanMessage("hello"))
            # await async_message_history.aget_messages()

    0.2.21.0session_maker)removalalternativer&   c                     | j                   S rK   )rX   r6   s    r,   r   zSQLChatMessageHistory.Session   s     !!!r/   Nr1   connection_stringr>   session_id_field_namecustom_message_converter
connectionengine_args
async_modec	                 "   |r	|rJ d       |r t         st        dddd       da |}|| _        t        |t              r6|| _        |rt        |fi |xs i | _        n`t        dd|i|xs i | _	        nIt        |t              rd	| _        || _	        n*t        |t              rd| _        || _        nt        d
      |  | j
                  rt        | j                        | _        n$t        t!        | j                              | _        || _        |xs t%        |      | _        | j&                  j)                         | _        t-        | j*                  |      st        d      d	| _        | j
                  s| j1                          || _        y)a&  Initialize with a SQLChatMessageHistory instance.

        Args:
            session_id: Indicates the id of the same session.
            connection_string: String parameter configuration for connecting
                to the database.
            table_name: Table name used to save data.
            session_id_field_name: The name of field of `session_id`.
            custom_message_converter: Custom message converter for converting
                database data and `BaseMessage`
            connection: Database connection object, which can be a string containing
                connection configuration, Engine object or AsyncEngine object.
            engine_args: Additional configuration for creating database engines.
            async_mode: Whether it is an asynchronous connection.
        z7connection_string and connection are mutually exclusiverV   rW   r\   r_   )sincerY   namerZ   TurlFzconnection should be a connection string or an instance of sqlalchemy.engine.Engine or sqlalchemy.ext.asyncio.engine.AsyncEngine)bindz+SQL model class must have session_id columnNr=   )_warned_once_alreadyr   r\   
isinstancer<   ra   r   async_enginer   enginer   r   
ValueErrorr"   rX   r    r!   r]   rI   	converterr7   sql_model_classhasattr_table_created_create_table_if_not_existsr1   )	r+   r1   r\   r>   r]   r^   r_   r`   ra   s	            r,   rM   zSQLChatMessageHistory.__init__   s}   4 &* 	
E	
5 '!!, ,	 (,$*J%6D"j#&(DO$7%#.#4"%! ,R
R{?PbR
F+#DO$DK
K0"DO *DX  	??!39J9J!KD!/$++0N!OD%:"1X5LZ5X#~~AACt++-BCJKK#,,.$r/   c                 p    | j                   j                  j                  | j                         d| _        y )NT)rm   metadata
create_allrj   ro   r6   s    r,   rp   z1SQLChatMessageHistory._create_table_if_not_exists   s(    %%00="r/   c                 d  K   | j                   s| j                  sJ d       | j                  j                         4 d {   }|j	                  | j
                  j                  j                         d {    d d d       d {    d| _         y y 7 T7 7 # 1 d {  7  sw Y   !xY ww)Nz*This method must be called with async_modeT)ro   ra   ri   beginrun_syncrm   rr   rs   )r+   conns     r,   _acreate_table_if_not_existsz2SQLChatMessageHistory._acreate_table_if_not_exists   s     ""??P$PP?((..0 N NDmmD$8$8$A$A$L$LMMMN N"&D	 #NMN N N NsY   >B0 BB03B7B8B<B0BB0BB0B-!B$"B-)B0c                    | j                         5 }|j                  | j                        j                  t	        | j                  | j
                        | j                  k(        j                  | j                  j                  j                               }g }|D ],  }|j                  | j                  j                  |             . |cddd       S # 1 sw Y   yxY wzRetrieve all messages from dbN)_make_sync_sessionqueryrm   wheregetattrr]   r1   order_byrE   ascappendrl   r-   )r+   sessionresultmessagesrecords        r,   r   zSQLChatMessageHistory.messages   s     $$& 	'd223D00$2L2LM' $..115578  H  G = =f EFG	 	 	s   B;CCc                     | j                   S rK   )r   r6   s    r,   get_messagesz"SQLChatMessageHistory.get_messages  s    }}r/   c                   K   | j                          d{    | j                         4 d{   }t        | j                        j	                  t        | j                  | j                        | j                  k(        j                  | j                  j                  j                               }|j                  |       d{   }g }|j                         D ],  }|j                  | j                  j                  |             . |cddd      d{    S 7 7 7 ]7 # 1 d{  7  sw Y   yxY wwrz   )rx   _make_async_sessionr   rm   r}   r~   r]   r1   r   rE   r   executescalarsr   rl   r-   )r+   r   stmtr   r   r   s         r,   aget_messagesz#SQLChatMessageHistory.aget_messages  s    //111++- 	 	t++,D00$2L2LM' $..115578  #??400FH ..* G = =f EFG	 	 	 	2	 1	 	 	 	sh   D?D!D?D$D?BD*D&	AD*D?D(D?$D?&D*(D?*D<0D31D<8D?r0   c                     | j                         5 }|j                  | j                  j                  || j                               |j                          ddd       y# 1 sw Y   yxY w)z&Append the message to the record in dbNr{   addrl   r4   r1   commitr+   r0   r   s      r,   add_messagez!SQLChatMessageHistory.add_message  sP    $$& 	'KK33GT__MNNN	 	 	s   AA  A)c                 b  K   | j                          d{    | j                         4 d{   }|j                  | j                  j	                  || j
                               |j                          d{    ddd      d{    y7 {7 d7 7 # 1 d{  7  sw Y   yxY ww)znAdd a Message object to the store.

        Args:
            message: A BaseMessage object to store.
        N)rx   r   r   rl   r4   r1   r   r   s      r,   aadd_messagez"SQLChatMessageHistory.aadd_message   s      //111++- 	# 	#KK33GT__MN.."""	# 	# 	# 	2	#"	# 	# 	# 	#sg   B/BB/BB/A	B<B=BB/BB/B/BB/B, B#!B,(B/r   c                     | j                         5 }|D ]7  }|j                  | j                  j                  || j                               9 |j                          d d d        y # 1 sw Y   y xY wrK   r   r+   r   r   r0   s       r,   add_messagesz"SQLChatMessageHistory.add_messages+  sa    $$& 	'# SDNN77QRSNN	 	 	s   AA''A0c                 p  K   | j                          d {    | j                         4 d {   }|D ]7  }|j                  | j                  j	                  || j
                               9 |j                          d {    d d d       d {    y 7 7 k7 7 # 1 d {  7  sw Y   y xY wwrK   )rx   rX   r   rl   r4   r1   r   r   s       r,   aadd_messagesz#SQLChatMessageHistory.aadd_messages2  s     //111%%' 	# 	#7# SDNN77QRS.."""	# 	# 	# 	2	# #	# 	# 	# 	#sg   B6BB6BB6AB!BB!B6BB6B6B!B6!B3'B*(B3/B6c                 4   | j                         5 }|j                  | j                        j                  t	        | j                  | j
                        | j                  k(        j                          |j                          ddd       y# 1 sw Y   yxY wzClear session memory from dbN)	r{   r|   rm   filterr~   r]   r1   r   r   r+   r   s     r,   clearzSQLChatMessageHistory.clear:  sy     $$& 	'MM$../66,,d.H.HI??# fhNN	 	 	s   A4BBc                   K   | j                          d{    | j                         4 d{   }t        | j                        j	                  t        | j                  | j                        | j                  k(        }|j                  |       d{    |j                          d{    ddd      d{    y7 7 7 17 7 # 1 d{  7  sw Y   yxY wwr   )
rx   r   r   rm   r   r~   r]   r1   r   r   )r+   r   r   s      r,   aclearzSQLChatMessageHistory.aclearD  s      //111++- 	# 	#$../66,,d.H.HI??#D //$'''.."""	# 	# 	# 	2	#
 ("	# 	# 	# 	#sy   C$CC$CC$A$CC	C/C0C4C$?C C$C$	CCC$C!CC!C$c              #      K   | j                   rt        d      | j                         5 }t        t        |       ddd       y# 1 sw Y   yxY ww)Make an async session.zsAttempting to use a sync method in when async mode is turned on. Please use the corresponding async method instead.N)ra   rk   rX   r   
SQLSessionr   s     r,   r{   z(SQLChatMessageHistory._make_sync_sessionP  sS      ??E  ! 	,Wz7++	, 	, 	,s   (AA	AAAc                   K   | j                   st        d      | j                         4 d{   }t        t        |       ddd      d{    y7 (7 # 1 d{  7  sw Y   yxY ww)r   ztAttempting to use an async method in when sync mode is turned on. Please use the corresponding async method instead.N)ra   rk   rX   r   r   r   s     r,   r   z)SQLChatMessageHistory._make_async_session[  sn      E  %%' 	. 	.7|W--	. 	. 	. 	. 	. 	. 	.sD   ,A0AA0AA0AA0A0A-!A$"A-)A0)Nmessage_storer1   NNNN)r&   N))r8   r9   r:   r;   propertyr   r   r    r"   r   r<   r
   r$   DBConnectionr   r   boolrM   rp   rx   r	   r   r   r   r   r   r   r   r   r   r   r   
contextlibcontextmanagerr   r   r{   asynccontextmanagerr   r   r   r=   r/   r,   rU   rU   x   s   8 OD"~/AAB " E " ,0)%1CG0404%)M%M% $C=M% 	M%
  #M% #++?"@M% $,-M% d38n-M% TNM%^#' ${+   d;/ T+%6 $; 4 	#+ 	#$ 	#Xk%: t #H[,A #d #
# ,Ij$.D$E , , ##.>,:L+M . $.r/   rU   ):r   rO   loggingabcr   r   typingr   r   r   r   r	   r
   r   r   r   langchain_core._apir   r   
sqlalchemyr   r   r   r   r   sqlalchemy.ormr   ImportErrorsqlalchemy.ext.declarativelangchain_core.chat_historyr   langchain_core.messagesr   r   r   r   sqlalchemy.enginer   sqlalchemy.ext.asyncior   r   r   r   r   r    r!   r"   type	getLoggerr8   loggerr$   r<   rG   rI   r   rg   rU   r=   r/   r,   <module>r      s      #
 
 
 < < <</ ? 
 % $ 
 A9
 
		8	$"3 "&S s s . 2  $ [&#-. l.2 l.E  <;<4  A2TGR@As$   C ?C CCC10C1