
    g3fiW                       d dl mZ d dlZd dlZd dlZd dlZd dl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 d dlmZ d dlmZ d d	lmZmZmZmZmZmZmZmZm Z   ejB                  e"      Z# G d
 dee$   ee      Z%e%Z& G d de      Z'y)    )annotationsN)defaultdict)AsyncIteratorIteratorSequence)AbstractAsyncContextManagerAbstractContextManager	ExitStack)TracebackType)Any)RunnableConfig)	WRITES_IDX_MAPBaseCheckpointSaverChannelVersions
CheckpointCheckpointMetadataCheckpointTupleSerializerProtocolget_checkpoint_idget_checkpoint_metadatac                      e Zd ZU dZded<   ded<   ded<   ded		 	 	 	 	 d fd
ZddZ	 	 	 	 	 	 	 	 ddZddZ		 	 	 	 	 	 	 	 ddZ
	 	 	 	 	 	 	 	 d dZd!dZdddd	 	 	 	 	 	 	 	 	 d"dZ	 	 	 	 	 	 	 	 	 	 d#dZ	 d$	 	 	 	 	 	 	 	 	 d%dZd&dZd!dZdddd	 	 	 	 	 	 	 	 	 d'dZ	 	 	 	 	 	 	 	 	 	 d#dZ	 d$	 	 	 	 	 	 	 	 	 d%dZd&dZd(dZ xZS ))InMemorySavera  An in-memory checkpoint saver.

    This checkpoint saver stores checkpoints in memory using a `defaultdict`.

    Note:
        Only use `InMemorySaver` for debugging or testing purposes.
        For production use cases we recommend installing [langgraph-checkpoint-postgres](https://pypi.org/project/langgraph-checkpoint-postgres/) and using `PostgresSaver` / `AsyncPostgresSaver`.

        If you are using LangSmith Deployment, no checkpointer needs to be specified. The correct managed checkpointer will be used automatically.

    Args:
        serde: The serializer to use for serializing and deserializing checkpoints.

    Example:
        ```python
        import asyncio

        from langgraph.checkpoint.memory import InMemorySaver
        from langgraph.graph import StateGraph

        builder = StateGraph(int)
        builder.add_node("add_one", lambda x: x + 1)
        builder.set_entry_point("add_one")
        builder.set_finish_point("add_one")

        memory = InMemorySaver()
        graph = builder.compile(checkpointer=memory)
        coro = graph.ainvoke(1, {"configurable": {"thread_id": "thread-1"}})
        asyncio.run(coro)  # Output: 2
        ```
    z_defaultdict[str, dict[str, dict[str, tuple[tuple[str, bytes], tuple[str, bytes], str | None]]]]storagezadefaultdict[tuple[str, str, str], dict[tuple[str, int], tuple[str, str, tuple[str, bytes], str]]]writesz@dict[tuple[str, str, str, str | int | float], tuple[str, bytes]]blobsN)serdefactoryc                  t         |   |        |d       | _         |t              | _         |       | _        t               | _        |t        urp| j                  j                  | j                         | j                  j                  | j                         | j                  j                  | j
                         y y )N)r   c                      t        t              S N)r   dict     b/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langgraph/checkpoint/memory/__init__.py<lambda>z(InMemorySaver.__init__.<locals>.<lambda>Z   s    {4'8 r#   )
super__init__r   r!   r   r   r
   stackr   enter_context)selfr   r   	__class__s      r$   r'   zInMemorySaver.__init__S   s     	u%89dmY
[
+%JJ$$T\\2JJ$$T[[1JJ$$TZZ0 &r#   c                :    | j                   j                          | S r    r(   	__enter__r*   s    r$   r.   zInMemorySaver.__enter__c   s    

r#   c                <    | j                   j                  |||      S r    r(   __exit__)r*   exc_type	exc_value	tracebacks       r$   r2   zInMemorySaver.__exit__g   s     zz""8Y	BBr#   c                B   K   | j                   j                          | S wr    r-   r/   s    r$   
__aenter__zInMemorySaver.__aenter__o   s     

s   c                D   K   | j                   j                  |||      S wr    r1   )r*   _InMemorySaver__exc_type_InMemorySaver__exc_value_InMemorySaver__tracebacks       r$   	__aexit__zInMemorySaver.__aexit__s   s!      zz"":{KHHs    c                    i }|j                         D ]P  \  }}||||f}|| j                  v s| j                  |   }|d   dk7  s3| j                  j                  |      ||<   R |S )Nr   empty)itemsr   r   loads_typed)	r*   	thread_idcheckpoint_nsversionschannel_valueskvkkvvs	            r$   _load_blobszInMemorySaver._load_blobs{   sy     *,NN$ 	CDAq]Aq1BTZZZZ^a5G#(,

(>(>r(BN1%	C r#   c                L   |d   d   }|d   j                  dd      }t        |      x}r| j                  |   |   j                  |      x}r|\  }}}| j                  |||f   j	                         }	| j
                  j                  |      }
t        |i |
d| j                  |||
d         i| j
                  j                  |      |	D cg c]%  \  }}}}||| j
                  j                  |      f' c}}}}|rd|||di	      S d	      S y| j                  |   |   x}rt        |j                               }||   \  }}}| j                  |||f   j	                         }	| j
                  j                  |      }
t        d|||dii |
d| j                  |||
d         i| j
                  j                  |      |	D cg c]%  \  }}}}||| j
                  j                  |      f' c}}}}|rd|||di	      S d	      S yc c}}}}w c c}}}}w )
a9  Get a checkpoint tuple from the in-memory storage.

        This method retrieves a checkpoint tuple from the in-memory storage based on the
        provided config. If the config contains a `checkpoint_id` key, the checkpoint with
        the matching thread ID and timestamp is retrieved. Otherwise, the latest checkpoint
        for the given thread ID is retrieved.

        Args:
            config: The config to use for retrieving the checkpoint.

        Returns:
            The retrieved checkpoint tuple, or None if no matching checkpoint was found.
        configurablerA   rB    rD   channel_versionsrA   rB   checkpoint_idN)config
checkpointmetadatapending_writesparent_config)getr   r   r   valuesr   r@   r   rI   maxkeys)r*   rP   rA   rB   rO   savedrQ   rR   parent_checkpoint_idr   checkpoint_idcrF   _checkpointss                   r$   	get_tuplezInMemorySaver.get_tuple   s     /<	#N377L-f55=5Y/>BB=QQuQ=B:
H&:i%NOVVX*.***@*@*L&! % ($*:*:%}kBT6U+  "ZZ33H=NT$ $?Jr1aQ

 6 6q 9:$ 0 +-61>1E- * "+ 	 R: #ll95mDD{D #K$4$4$6 7=H=W:
H&:i%NOVVX"jj44Z@&&)2-:-:) % ($*:*:%}kBT6U+  "ZZ33H=NT$ $?Jr1aQ

 6 6q 9:$ 0 +-61>1E-' 6 "7  E!$H$s   *H*Hfilterbeforelimitc             #    K   |r	|d   d   fn| j                   }|r|d   j                  d      nd}|rt        |      nd}|D ]  }| j                   |   j                         D ]_  }	||	|k7  rt	        | j                   |   |	   j                         d d      D ]#  \  }
\  }}}|r|
|k7  r|rt        |      x}r|
|k\  r(| j                  j                  |      |r#t        fd|j                         D              sh||d	k  r ||d
z  }| j                  ||	|
f   j                         }| j                  j                  |      }t        d||	|
dii |d| j                  ||	|d         i|rd||	|dind|D cg c]%  \  }}}}||| j                  j                  |      f' c}}}}       & b  yc c}}}}w w)a  List checkpoints from the in-memory storage.

        This method retrieves a list of checkpoint tuples from the in-memory storage based
        on the provided criteria.

        Args:
            config: Base configuration for filtering checkpoints.
            filter: Additional filtering criteria for metadata.
            before: List checkpoints created before this configuration.
            limit: Maximum number of checkpoints to return.

        Yields:
            An iterator of matching checkpoint tuples.
        rK   rA   rB   Nc                    | d   S )Nr   r"   )xs    r$   r%   z$InMemorySaver.list.<locals>.<lambda>  s
    !A$ r#   T)keyreversec              3  L   K   | ]  \  }}|j                  |      k(    y wr    )rU   ).0	query_keyquery_valuerR   s      r$   	<genexpr>z%InMemorySaver.list.<locals>.<genexpr>  s+      *2I{ $x||I'>>*s   !$r      rN   rD   rM   )rP   rQ   rR   rT   rS   )r   rU   r   rX   sortedr?   r   r@   allr   rV   r   rI   )r*   rP   rb   rc   rd   
thread_idsconfig_checkpoint_nsconfig_checkpoint_idrA   rB   rO   rQ   
metadata_brZ   before_checkpoint_idr   r[   r\   r]   rF   r^   rR   s                        @r$   listzInMemorySaver.list   sc    , @Ff^,[9;4<<
;AF>"&&7t 	 =C08# P	I!%i!8!=!=!? O(4%)== LL+M:@@B& 	H M $( ,AU0U  5Fv5NN1N)-AA   $zz55jAHc *6<lln* ' ! (UaZ*
![["M=Afh  /3jj.D.DZ.PK)*-61>1>- $)$,d.>.> ) - +,> ?/$ "*  4 !/1:5B5I1" "& SY( (CN2q!QRDJJ$:$:1$=>(9 SHOP	Z(s   FG*G5Gc           
        |j                         }|d   d   }|d   d   }|j                  d      }|j                         D ]:  \  }	}
|	|v r| j                  j	                  ||	         nd| j
                  |||	|
f<   < | j                  |   |   j                  |d   | j                  j	                  |      | j                  j	                  t        ||            |d   j                  d      fi       d|||d   diS )	a"  Save a checkpoint to the in-memory storage.

        This method saves a checkpoint to the in-memory storage. The checkpoint is associated
        with the provided config.

        Args:
            config: The config to associate with the checkpoint.
            checkpoint: The checkpoint to save.
            metadata: Additional metadata to save with the checkpoint.
            new_versions: New versions as of this write

        Returns:
            RunnableConfig: The updated config containing the saved checkpoint's timestamp.
        rK   rA   rB   rD   )r>   r#   r\   rO   rN   )
copypopr?   r   dumps_typedr   r   updater   rU   )r*   rP   rQ   rR   new_versionsr]   rA   rB   rV   rE   rF   s              r$   putzInMemorySaver.putF  s   * OO>*;7	~.?!"'7!8 &&( 	DAq56&[

&&vay1n JJ	=!Q78	 	Y.554 JJ**1-JJ**+B68+TU>*..?#	
 &!.!+D!1
 	
r#   c                f   |d   d   }|d   j                  dd      }|d   d   }|||f}| j                  j                  |      }	t        |      D ]^  \  }
\  }}|t        j                   ||
      f}|d   dk\  r|	r||	v r0||| j                  j                  |      |f| j                  |   |<   ` y)	a  Save a list of writes to the in-memory storage.

        This method saves a list of writes to the in-memory storage. The writes are associated
        with the provided config.

        Args:
            config: The config to associate with the writes.
            writes: The writes to save.
            task_id: Identifier for the task creating the writes.
            task_path: Path of the task creating the writes.

        Returns:
            RunnableConfig: The updated config containing the saved writes' timestamp.
        rK   rA   rB   rL   rO   ro   r   N)rU   r   	enumerater   r   r{   )r*   rP   r   task_id	task_pathrA   rB   rO   	outer_keyouter_writes_idxr]   rF   	inner_keys                 r$   
put_writeszInMemorySaver.put_writest  s    * >*;7	~.22?BG~.?}=		2$V, 
	KC!Q ."4"4Q"<=I|q ]yM7Q 

&&q)	1DKK	"9-
	r#   c                2   || j                   v r| j                   |= t        | j                  j                               D ]  }|d   |k(  s| j                  |=  t        | j                  j                               D ]  }|d   |k(  s| j                  |=  y)Delete all checkpoints and writes associated with a thread ID.

        Args:
            thread_id: The thread ID to delete.

        Returns:
            None
        r   N)r   rw   r   rX   r   )r*   rA   rE   s      r$   delete_threadzInMemorySaver.delete_thread  s     $Y'dkk&&() 	#Aty KKN	# djjoo'( 	"Aty JJqM	"r#   c                ,   K   | j                  |      S w)a|  Asynchronous version of `get_tuple`.

        This method is an asynchronous wrapper around `get_tuple` that runs the synchronous
        method in a separate thread using asyncio.

        Args:
            config: The config to use for retrieving the checkpoint.

        Returns:
            The retrieved checkpoint tuple, or None if no matching checkpoint was found.
        )r`   )r*   rP   s     r$   
aget_tuplezInMemorySaver.aget_tuple  s      ~~f%%   c              J   K   | j                  ||||      D ]  }| 	 yw)aQ  Asynchronous version of `list`.

        This method is an asynchronous wrapper around `list` that runs the synchronous
        method in a separate thread using asyncio.

        Args:
            config: The config to use for listing the checkpoints.

        Yields:
            An asynchronous iterator of checkpoint tuples.
        ra   N)rw   )r*   rP   rb   rc   rd   items         r$   alistzInMemorySaver.alist  s-     & IIfVF%IP 	DJ	s   !#c                2   K   | j                  ||||      S w)a  Asynchronous version of `put`.

        Args:
            config: The config to associate with the checkpoint.
            checkpoint: The checkpoint to save.
            metadata: Additional metadata to save with the checkpoint.
            new_versions: New versions as of this write

        Returns:
            RunnableConfig: The updated config containing the saved checkpoint's timestamp.
        )r~   )r*   rP   rQ   rR   r}   s        r$   aputzInMemorySaver.aput  s     $ xx
HlCC   c                2   K   | j                  ||||      S w)a  Asynchronous version of `put_writes`.

        This method is an asynchronous wrapper around `put_writes` that runs the synchronous
        method in a separate thread using asyncio.

        Args:
            config: The config to associate with the writes.
            writes: The writes to save, each as a (channel, value) pair.
            task_id: Identifier for the task creating the writes.
            task_path: Path of the task creating the writes.

        Returns:
            None
        )r   )r*   rP   r   r   r   s        r$   aput_writeszInMemorySaver.aput_writes  s     * vvw	BBr   c                ,   K   | j                  |      S w)r   )r   )r*   rA   s     r$   adelete_threadzInMemorySaver.adelete_thread  s      !!),,r   c                    |d}n0t        |t              r|}nt        |j                  d      d         }|dz   }t        j                         }|dd|dS )Nr   .ro   032016)
isinstanceintsplitrandom)r*   currentchannel	current_vnext_vnext_hs         r$   get_next_versionzInMemorySaver.get_next_version  s\    ?I%IGMM#.q12IQQvcl++r#   )r   zSerializerProtocol | Noner   ztype[defaultdict]returnNone)r   r   )r3   type[BaseException] | Noner4   BaseException | Noner5   TracebackType | Noner   bool | None)r9   r   r:   r   r;   r   r   r   )rA   strrB   r   rC   r   r   zdict[str, Any])rP   r   r   zCheckpointTuple | None)
rP   RunnableConfig | Nonerb   dict[str, Any] | Nonerc   r   rd   
int | Noner   zIterator[CheckpointTuple])
rP   r   rQ   r   rR   r   r}   r   r   r   )rL   )
rP   r   r   zSequence[tuple[str, Any]]r   r   r   r   r   r   )rA   r   r   r   )
rP   r   rb   r   rc   r   rd   r   r   zAsyncIterator[CheckpointTuple])r   z
str | Noner   r   r   r   )__name__
__module____qualname____doc____annotations__r   r'   r.   r2   r7   r<   rI   r`   rw   r~   r   r   r   r   r   r   r   r   __classcell__r+   s   @r$   r   r      so   B 
   ,0%0	1 )1 #	1
 
1 C,C (C (	C
 
CI.I *I *	I
 
I

-0
<K
	
Pl )-(, k%k &	k
 &k k 
#kZ,
,
 ,
 %	,

 &,
 
,
f $$ *$ 	$
 $ 
$L"$&$ )-(, % &	
 &  
(,DD D %	D
 &D 
D2 CC *C 	C
 C 
C.	-	,r#   r   c                  T     e Zd ZdZd	 fdZd
dZd
dZddZddZddZ	d
dZ
 xZS )PersistentDicta6  Persistent dictionary with an API compatible with shelve and anydbm.

    The dict is kept in memory, so the dictionary operations run as fast as
    a regular dictionary.

    Write to disk is delayed until close or sync (similar to gdbm's fast mode).

    Input file format is automatically discovered.
    Output file format is selectable between pickle, json, and csv.
    All three serialization formats are backed by fast C implementations.

    Adapted from https://code.activestate.com/recipes/576642-persistent-dict-with-multiple-standard-file-format/

    c               \    d| _         d | _        d| _        || _        t	        |   |i | y )Nr]   pickle)flagmodeformatfilenamer&   r'   )r*   r   argskwdsr+   s       r$   r'   zPersistentDict.__init__%  s1    		 $'$'r#   c                   | j                   dk(  ry| j                  dz   }t        || j                  dk(  rdnd      }	 | j	                  |       	 |j                          t        j                  || j                         | j                  +t        j                  | j                  | j                         yy# t
        $ r t        j                  |        w xY w# |j                          w xY w)zWrite dict to diskrNz.tmpr   wbw)r   r   openr   dump	Exceptionosremovecloseshutilmover   chmod)r*   tempnamefileobjs      r$   synczPersistentDict.sync,  s    99==6)x)@cJ	IIg
 MMOHdmm,99 HHT]]DII. !  	IIh	 MMOs   B8 8 CC C-c                D    | j                          | j                          y r    )r   clearr/   s    r$   r   zPersistentDict.close=  s    		

r#   c                    | S r    r"   r/   s    r$   r.   zPersistentDict.__enter__A  s    r#   c                $    | j                          y r    )r   )r*   exc_infos     r$   r2   zPersistentDict.__exit__D  s    

r#   c                    | j                   dk(  r!t        j                  t        |       |d       y t	        dt        | j                         z         )Nr      zUnknown format: )r   r   r   r!   NotImplementedErrorrepr)r*   r   s     r$   r   zPersistentDict.dumpG  s<    ;;("KKT
GQ/%&84;L&LMMr#   c                   | j                   dk(  ry t        | j                  | j                  dk(  rdnd      5 }t        j
                  fD ]5  }|j                  d       	 | j                   ||            c cd d d        S  t        d      # t        $ r Y  d d d        y t        $ r$ t        j                  d|j                           w xY w# 1 sw Y   y xY w)Nnr   rbr   r   zFailed to load file: zFile not in a supported format)r   r   r   r   r   loadseekr|   EOFErrorr   loggererrorname
ValueError)r*   r   loaders      r$   r   zPersistentDict.loadM  s    99$--)@cJ 
	?g!;;. Q;;vg77	
	? 
	? =>>   
	? 
	? ! LL#8!GH
	? 
	?s5   &CB5CC	CC!,CCC)r   r   r   r   r   r   r   r   )r   r   )r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   r'   r   r   r.   r2   r   r   r   r   s   @r$   r   r     s,    (/"N?r#   r   )(
__future__r   loggingr   r   r   r   collectionsr   collections.abcr   r   r   
contextlibr   r	   r
   typesr   typingr   langchain_core.runnablesr   langgraph.checkpoint.baser   r   r   r   r   r   r   r   r   	getLoggerr   r   r   r   MemorySaverr   r"   r#   r$   <module>r      s    "  	    # = = U U   3
 
 
 
		8	$p,46Qp,f F?[ F?r#   