
    k
iB[                      d Z ddlmZ ddlZddlZddl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mZ ddlZddlmZ dd	lmZmZ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) ddl*m+Z+ ddl,m-Z- ddl.m/Z/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z< ddl=m>Z>m?Z?m@Z@mAZAmBZB  ejC        eD          ZE G d de9ee&e)f         e+f                   ZFdS )z/Async implementation of Redis checkpoint saver.    )annotationsN)defaultdict)asynccontextmanager)TracebackType)
AnyAsyncIteratorDictListOptionalSequenceTupleTypeUnioncast)RunnableConfig)WRITES_IDX_MAPChannelVersions
CheckpointCheckpointMetadataCheckpointTuplePendingWriteget_checkpoint_id)TASKS)Redis)RedisCluster)AsyncSearchIndex)FilterQuery)NumTag)RedisConnectionFactoryULID)CHECKPOINT_PREFIXCHECKPOINT_WRITE_PREFIXREDIS_KEY_SEPARATORBaseRedisSaver)AsyncCheckpointKeyRegistry)EMPTY_ID_SENTINELfrom_storage_safe_idfrom_storage_safe_strto_storage_safe_idto_storage_safe_strc            	          e Zd ZU dZded<   ded<   ded<   ded<   d	Zd
ed<   d	Zded<   	 dpd	d	d	eeddq fdZ		 	 	 drdsdZ
dtdZdud Zdvd$Zdwd%Zdxd,Zdtd-Zdtd.Zdtd/Z	 	 dydzd6Zd{d:Zd	d	d	d;d|dBZ	 d}d~dKZ	 dddPZ	 dddQZ	 dddSZd{dTZddUZee	 dpd	d	d	eedddW                        Z	 	 	 dddYZ	 ddd\Z 	 	 ddd^Z!ddbZ"dddZ#ddeZ$dfd	dgdhddoZ% xZ&S )AsyncRedisSaverzAsync Redis implementation for checkpoint saver.

    Supports standard Redis URLs (redis://), SSL (rediss://), and
    Sentinel URLs (redis+sentinel://host:26379/service_name/db).
    str
_redis_urlr   checkpoints_indexcheckpoint_writes_indexz$Union[AsyncRedis, AsyncRedisCluster]_redisNzOptional[bool]cluster_modezOptional[AsyncKeyRegistry]_key_registry)redis_clientconnection_argsttlcheckpoint_prefixcheckpoint_write_prefix	redis_urlOptional[str]r6   .Optional[Union[AsyncRedis, AsyncRedisCluster]]r7   Optional[Dict[str, Any]]r8   r9   r:   returnNonec                   t                                          ||||||           t          j                    | _        i | _        d| _        t          | _        d S )Nr;   r6   r7   r8   r9   r:     )	super__init__asyncioget_running_looploop
_key_cache_key_cache_max_sizer%   
_separator)selfr;   r6   r7   r8   r9   r:   	__class__s          C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\site-packages\langgraph/checkpoint/redis/aio.pyrE   zAsyncRedisSaver.__init__V   sf     	%+/$; 	 	
 	
 	
 ,..	 +-#' -    c                `    |du | _         |t          j        |fi |pi | _        dS || _        dS )zConfigure the Redis client.

        Supports standard Redis URLs (redis://), SSL (rediss://), and
        Sentinel URLs (redis+sentinel://host:26379/service_name/db).
        N)_owns_its_clientr    get_async_redis_connectionr3   )rL   r;   r6   r7   s       rN   configure_clientz AsyncRedisSaver.configure_clientp   sQ     !- 40K -3 DKKK 'DKKKrO   c                    t          j        | j        | j                  | _        t          j        | j        | j                  | _        dS )z+Create indexes without connecting to Redis.)r6   N)r   	from_dictcheckpoints_schemar3   r1   writes_schemar2   rL   s    rN   create_indexeszAsyncRedisSaver.create_indexes   sR    !1!;#$+"
 "
 "
 (8'AT[(
 (
 (
$$$rO   	thread_idcheckpoint_nscheckpoint_idc                j   d| d| d| }|| j         v r| j         |         S t          t          |                    }t          |          }t          t          |                    }| j                            | j        |||g          }t          | j                   | j        k     r
|| j         |<   |S )z&Optimized key generation with caching.zckpt::)	rI   r/   r+   r,   rK   join_checkpoint_prefixlenrJ   )	rL   rZ   r[   r\   	cache_keysafe_thread_idsafe_checkpoint_nssafe_checkpoint_idkeys	            rN   !_make_redis_checkpoint_key_cachedz1AsyncRedisSaver._make_redis_checkpoint_key_cached   s    
 HIGGGGGG	 ''?9-- /	::;;0?? !3M!B!BCC o""'""	
 
 t$":::),DOI&
rO   task_ididxOptional[int]c           
        d| d| d| d| d| 
}|| j         v r| j         |         S t          t          |                    }t          |          }t          t          |                    }	| j        |||	|g}
|"|
                    t          |                     | j                            |
          }t          | j                   dk     r
|| j         |<   |S )z-Optimized writes key generation with caching.zwrite:r^   N'  )	rI   r/   r+   r,   _checkpoint_write_prefixappendrK   r_   ra   )rL   rZ   r[   r\   rh   ri   rb   rc   rd   re   	key_partsrf   s               rN   (_make_redis_checkpoint_writes_key_cachedz8AsyncRedisSaver._make_redis_checkpoint_writes_key_cached   s    YYXXXXXXXXSVXX	 ''?9-- /	::;;0?? !3M!B!BCC )
	 ?SXX&&& o""9-- t%''),DOI&
rO   c                r   K   |                                   d{V  |                                  d{V  | S )zAsync context manager enter.N)asetupaset_client_inforX   s    rN   
__aenter__zAsyncRedisSaver.__aenter__   sQ      kkmm ##%%%%%%%%%rO   	_exc_typeOptional[Type[BaseException]]_exc_valOptional[BaseException]_exc_tbOptional[TracebackType]c                  K   | j         rw| j                                         d{V  t          | j        dd          r(| j        j                                        }|r| d{V  d| j        _        d| j        _        dS dS )zAsync context manager exit.Nconnection_pool)	rQ   r3   aclosegetattrr|   
disconnectr1   _redis_clientr2   )rL   ru   rw   ry   coros        rN   	__aexit__zAsyncRedisSaver.__aexit__   s         	>+$$&&&&&&&&&t{$5t<< {2==?? JJJJJJJ 48D"09=D(666	> 	>rO   c                  K   |                                   | j                            d           d{V  | j                            d           d{V  |                                  d{V  t          | j                  | _        dS )zSet up the checkpoint saver.F)	overwriteN)rY   r1   creater2   _detect_cluster_modeAsyncKeyRegistryr3   r5   rX   s    rN   rr   zAsyncRedisSaver.asetup   s      $++e+<<<<<<<<<*11E1BBBBBBBBB ''))))))))) .dk::rO   c                >   K   |                                   d{V  dS )a1  Set up the checkpoint saver asynchronously.

        This method creates the necessary indices in Redis and detects cluster mode.
        It MUST be called before using the checkpointer.

        This async method follows the canonical pattern used by PostgreSQL and SQLite
        checkpointers in the LangGraph ecosystem. The type ignore is necessary because
        the base class defines a sync setup() method, but async checkpointers require
        an async setup() method to properly handle coroutines.

        Usage: await checkpointer.setup()
        N)rr   rX   s    rN   setupzAsyncRedisSaver.setup   s.       kkmmrO   c                  K   | j         %t                              d| j          d           dS t          | j        t
                    r#t                              d           d| _         dS t                              d           d| _         dS )zGDetect if the Redis client is a cluster client by inspecting its class.Nz%Redis cluster_mode explicitly set to z, skipping detection.z Redis client is a cluster clientTz#Redis client is a standalone clientF)r4   loggerinfo
isinstancer3   AsyncRedisClusterrX   s    rN   r   z$AsyncRedisSaver._detect_cluster_mode  s      (KK`8I```   F dk#455 	&KK:;;; $DKK=>>> %DrO   main_keyrelated_keysOptional[list[str]]ttl_minutesOptional[float]r   c                  K   |*| j         r#d| j         v r| j                             d          }||dk    r[|g|pg z   }|D ]N}	 | j                            |           d{V  $# t          $ r t
                              d|           Y Kw xY wdS t          |dz            }|g|pg z   }|D ]O}	 | j                            ||           d{V  %# t          $ r t
                              d|           Y Lw xY wdS dS )a  Apply Redis native TTL to keys asynchronously.

        Args:
            main_key: The primary Redis key
            related_keys: Additional Redis keys that should expire at the same time
            ttl_minutes: Time-to-live in minutes, overrides default_ttl if provided
                        Use -1 to remove TTL (make keys persistent)

        Returns:
            Result of the Redis operation
        Ndefault_ttlz!Failed to remove TTL from key: %sT<   zFailed to apply TTL to key: %s)	
ttl_configgetr3   persist	Exceptionr   warningintexpire)rL   r   r   r   all_keysrf   ttl_secondss          rN   _apply_ttl_to_keysz"AsyncRedisSaver._apply_ttl_to_keys  s     "  A=DO#C#C"o11-@@"b   %:);<# Q QCQ"k11#6666666666$ Q Q Q'JCPPPPPQ t kB.//K
 !z\%7R8H J JJ+,,S+>>>>>>>>>>  J J JNN#CSIIIIIJ 47 #"s$    A%%%BB1!C%C;:C;configr   Optional[CheckpointTuple]c           
     $  K   |d         d         }t          |          }|d                             dd          }t          |          }t          |          }|r|t          k    rt          |          }|                     |||          }| j                            d          }	|	                                                    |           | j	        r/| j	                            d          r|	
                    |           |	                                 d{V }
|
d	         }|sdS d}| j	        r"| j	                            d          r|
d
         }|                    d|          |                    d|          |                    d|          |                    d|          t          j        |                    di                     |                    dd          d}nd| d| }| j                            |           d{V }|sdS | j                            d          }	|	                                                    |           | j	        r/| j	                            d          r|	
                    |           |	                                 d{V }
|
d	         }|sdS d}| j	        r"| j	                            d          r|
d
         }|                    d|          |                    d|          |                    d          |                    d          t          j        |                    di                     |                    dd          d}t          |d                   }t          |d                   }t          |d                   }t          |d                   }| j	        r9| j	                            d          rdt                      vr^|                     t          |          t          |          t          |                    }| j        
                    |           d{V }|d	k    rg }| j        r"| j                            |||           d{V }|                     ||r|nd           d{V  | j        rX| j	        rQ| j	                            d          }|5t'          |dz            }| j                            ||||           d{V  t+          |t,                    r|                    d          nt/          |dd          }t+          |t0                    rt          j        |          }n|}|r|                    d          nd}g }|                    |                     ||||                     |r+|                    |                     |||                     |                    |                     |||                     |r@t=          j        |  d{V }|                      |d	                   }|d
         }|d         }n9t=          j        |  d{V }|                      |d	                   }g }|d
         }t+          |t,                    r|                    dd          nt/          |dd          }t+          |t0                    rt          j        |          n|}d |!                                D             } tE          tF          |           }!d|||di}"|d         }t+          |t,                    rt          j        |          }| $                    |||          }#d}$|rd|||di}$tK          |"|#|!|$|          S )z1Get a checkpoint tuple from Redis asynchronously.configurablerZ   r[    Ftransactionrefresh_on_readNr      r\   parent_checkpoint_id
checkpointmetadata{})rZ   r[   r\   r   $.checkpoint
$.metadatacheckpoint_latest:r^   current_ttlr   r   r   channel_versions)rZ   r[   r\   r   )rZ   r[   r      r   c                    i | ]G\  }}|                     d d          t          |t                    r|                     d d          n|HS  r   replacer   r/   .0kvs      rN   
<dictcomp>z.AsyncRedisSaver.aget_tuple.<locals>.<dictcomp>4  sa     
 
 
 1 IIh##+5a+=+=D		(B'''1
 
 
rO   rZ   r[   r\   r   r   r   parent_configpending_writes)&r   r   r+   r,   r(   _make_redis_checkpoint_keyr3   pipelinejsonr   r8   executedumpsr)   r*   localsr5   get_write_keysr   r   	apply_ttlr   dictr~   r/   loadsrn   aget_channel_values_aload_pending_sends_aload_pending_writesrF   gather_recursive_deserializeitemsr   r   _load_checkpointr   )%rL   r   rZ   r\   r[   storage_safe_thread_idstorage_safe_checkpoint_nsstorage_safe_checkpoint_idcheckpoint_keyr   pipeline_resultscheckpoint_datar   doclatest_pointer_keydoc_thread_iddoc_checkpoint_nsdoc_checkpoint_iddoc_parent_checkpoint_id
write_keysr   r   checkpoint_rawcheckpoint_data_dict channel_versions_from_checkpointtasksresultschannel_valuespending_sendsr   raw_metadatametadata_dictsanitized_metadatar   config_paramcheckpoint_paramr   s%                                        rN   
aget_tuplezAsyncRedisSaver.aget_tupleR  s'	     >*;7	)&11~.22?BGG "4I!>!>%8%G%G" ^	].???);M)J)J& "<<&** N {+++>>H MMOO///  -4?#6#67H#I#I -^,,, &.%5%5%7%7777777.q1O" t K 24?#6#67H#I#I 2.q1 -00>TUU!0!4!4#%?" " "1!4!4#%?" " )8(;(;*,F) ) !%
?+>+>|R+P+P Q Q-11  CC$ "l6L!k!kOi!k!k#';??3E#F#FFFFFFFN! t {+++>>H MMOO///  -4?#6#67H#I#I -^,,, &.%5%5%7%7777777.q1O" t K 24?#6#67H#I#I 2.q1 -00>TUU!0!4!4#%?" " "1!4!4_!E!E(7(;(;<R(S(S $
?+>+>|R+P+P Q Q-11  C -S-=>>1#o2FGG0_1EFF#7<R8S#T#T  ? )	t223DEE )	FHH,,!%!@!@&}55'(9::&'899" "
 %)KOON$C$CCCCCCC Q
% '+'9'H'H%'8:K( ( " " " " " "J
 --"*$FJJ$        
 % 
$/ 
"&/"5"5m"D"DK".&)+*:&;&;"0::)--'	         #t$$4CGGN###nd33 	
 nc** 	2#':n#=#=  #1  $ $$%7888 	)  	$$'//!A	 %  	
 	
 	
 $ 	LL))'"3)A *     	&&y-ARSS	
 	
 	

 $ 
	(#NE2222222G-1-H-HQR-T-TNAHM18NN $NE2222222G!88DDNM$QZN
 #t$$2CGGL$'''lD11 	 )3<(E(EWDJ|$$$< 	

 
 &++--	
 
 
 *,>?? &!.!2 (
 n-ot,, 	:"j99O00
 
 04# 	!*%2%=! !M '')
 
 
 	
rO   )filterbeforelimitOptional[RunnableConfig]r   Optional[dict[str, Any]]r   r   AsyncIterator[CheckpointTuple]c                K   g }|r#|                     t          d          t          |d         d                   k               |d                             d          x}r3|                     t          d          t          |          k               |d                             d          x}r3|                     t          d          t	          |          k               t          |          x}r3|                     t          d          t          |          k               |r|                                D ]\  }	}
|	dk    r'|                     t          d          |
k               2|	dk    r'|                     t          d          |
k               _|	dk    r4|                     t          d          t          |
          k               |	dk    r4|                     t          d          t          |
          k               t          d|	           |rdt          |          }|rS	 t          j
        |          }|j        }|                     t          d	          |k                n# t          $ r Y nw xY w|r|d
         nd}|dd         D ]}||z  }t          |g d|pdd          }| j                            |           d{V }g }g }g }|j        D ]}t#          |d          r|j        ni }t'          |d                   }t)          |d                   }t'          |d                   }t'          |d                   }|                    d          pt+          |dd          }|rtt-          |t.                    r
|r|d
         }t-          |t0                    r|nt3          j        |          }|                     |                    di                     }ni }|r |dk    r|||f}|                     |           |                    d          pt+          |dd          }|dk    rd}n|dk    s|dk    rd}|r|||f}|                     |           |                     ||||||||r|nd||d
           i }|r|                     |           d{V }i }|r|                     |           d{V }|D ]} | d         }| d         }| d         }| d         }g }!|r|||f}|                    |g           }!| d         }|                    d          pt+          | d          dd!          }"t-          |"t<                    rt3          j        |"          n|"}#t?          d" |#                                 D                       r4d# |#                                D             }$tC          tD          |$          }%ntC          tD          |#          }%d|||d$i}&| #                    | d%         r| d&         n| d          d         | d         |!          }'g }(| d         r|||f}|                    |g           }(d})|rd|||d$i})tI          |&|'|%|)|('          W V  dS )(z+List checkpoints from Redis asynchronously.rZ   r   run_idr[   r\   sourcestepzUnsupported filter key: checkpoint_tsr   *r   N)rZ   r[   r\   r   r   r   
has_writesrl   )r\   DESC)filter_expressionreturn_fieldsnum_resultssort_by__dict__r   r   r   r@   r   FtrueTfalseFalse)
r   doc_dictrZ   r[   r\   r   r   checkpoint_dictr   r   r  r   r   r   c              3  b   K   | ]*}t          |t                    d t          |          v V  +dS )r   N)r   r/   )r   r   s     rN   	<genexpr>z(AsyncRedisSaver.alist.<locals>.<genexpr>#  sR        '(jQRTWFXFXCFF"     rO   c                    i | ]G\  }}|                     d d          t          |t                    r|                     d d          n|HS r   r   r   s      rN   r   z)AsyncRedisSaver.alist.<locals>.<dictcomp>&  sa     & & & 1 IIh++3=a3E3EL		(B///1& & &rO   r   r   r  r   )%rn   r   r+   r   r,   r   r   r   
ValueErrorr"   from_str	timestampr   r   r1   searchdocshasattrr   r)   r*   r~   r   listr   orjsonr   r   _abatch_load_pending_sends_abatch_load_pending_writesr/   anyvaluesr   r   r   r   )*rL   r   r   r   r   r   r   r[   r\   r   r   before_checkpoint_idbefore_ulid	before_tscombined_filterexprqueryr   all_docs_datapending_sends_batch_keyspending_writes_batch_keysr   r  rZ   r   r   r  r   	batch_keycheckpoint_has_writespending_sends_mappending_writes_mapdoc_datar   r   r   r   r   r   r   r   r   s*                                             rN   alistzAsyncRedisSaver.alistc  s       	$$K  %f^&<[&IJJK    /33H===v V!((X:LV:T:T)TUUU !'~ 6 : :? K KK} !((((,?,N,NN   !2& 9 99} !((((,>},M,MM    	E 
E 
E1==%,,S]]a-?@@@@&[[%,,S[[A-=>>>>+%%%,,S-=-=ASTUAVAV-VWWWW(]]%,,S]]>PQR>S>S-STTTT$%C%C%CDDD 
	#4V#<#< # "&-0D"E"EK + 5I%,,S-A-AI-MNNNN    D
 3DL+A..%abb) 	$ 	$Dt#OO -   -
 
 
  .55e<<<<<<<< #% $&!< A	 A	C'.sJ'?'?Gs||RH,S-=>>I1#o2FGGM0_1EFFM#7<R8S#T#T  'll>:: g^T? ?O  $ot44 9 9&5a&8O
 "/4887OOo66  
 "&!<!<#''(8"==" " "$ $ ;(<(F(F&7KL	(//	::: %-LL$>$> %'\5C C! %..(,%%&'115Jg5U5U(-%$ <&}E	)00;;;    (!*%2%2,@'6:I'St&4"7      # 	&*&E&E(' ' ! ! ! ! ! !
  $ 	'+'G'G)( ( " " " " " "
 & Q	 Q	H -I$_5M$_5M#+,B#C  BDM# E&7KL	 1 5 5i D D  
+H#<<55 t: :L lC00"\***!    ,9,@,@,B,B     C& & !. 3 3 5 5	& & &"   24FGG 2MBB !*%2%2! !,L  $44   129H.//!%8)*    24N% G&}E	!3!7!7	2!F!F 48M# "%.)6)=% %! "#+!+-       WQ	 Q	s   :AI< <
J	J	r  r   r   r   r   new_versionsr   stream_modec                	  K   |d                                          }|                    d                    d                    }|                    d          }|                    d          }	|                    dd          }
|                    dd          }|
p|p|                    d	d          }d}|                    d	          r%|
r#|                    d	          |
k    r
|
}|d	         }t          |          }t	          |	          }t          |          }|                                 }d||	|d
i}	 d}|rJ	 ddlm}  |j        |          }|j        }n+# t          $ r ddl
}|
                                dz  }Y nw xY w||rt          |          nd|||rt          |          nd||                     |          |                               dd	}t          fddD                       rd         |d<   d         |d<   |                     ||	|          }d}| j        r&d| j        v rt!          | j        d         dz            }| j                            |g|g|           d{V  | j        r`| j        rYd| j        v rP|N	 | j                            ||           d{V  n+# t          $ r t,                              d|           Y nw xY wd| d| }| j                            ||           d{V  |N	 | j                            ||           d{V  n+# t          $ r t,                              d|           Y nw xY w|S # t2          j        $ rX |dv rQ	 ||rt          |          nd|||                    d          r0t          t7          |                    dd                              nd|                     |          |                     i d|d          dd}|                     |||          }| j        r5| j                                                            |d |           d{V  n^| j                            d!          }|                                                    |d |           |                                 d{V  n# t          $ r Y nw xY w t          $ r}|d}~ww xY w)"a2  Store a checkpoint to Redis with proper transaction handling.

        This method ensures that all Redis operations are performed atomically
        using Redis transactions. In case of interruption (asyncio.CancelledError),
        the transaction will be aborted, ensuring consistency.

        Args:
            config: The config to associate with the checkpoint
            checkpoint: The checkpoint data to store
            metadata: Additional metadata to save with the checkpoint
            new_versions: New channel versions as of this write
            stream_mode: The streaming mode being used (values, updates, etc.)

        Returns:
            Updated configuration after storing the checkpoint

        Raises:
            asyncio.CancelledError: If the operation is cancelled/interrupted
        r   r   rZ   r[   r\   N	thread_tsr   idr   r   r!   rC   F)	rZ   r   r[   r\   r   r   r   r   r   c              3      K   | ]}|v V  	d S N )r   rf   r   s     rN   r  z'AsyncRedisSaver.aput.<locals>.<genexpr>  s'      AAs3(?AAAAAArO   )r   r   r   r   r   r   )keysr8   z)Failed to apply TTL to checkpoint key: %sr   r^   z-Failed to apply TTL to latest pointer key: %s)r  messagesr   T)interruptedr%  )rZ   r   r[   r\   r   r   r   r   $r   ) copypopr   r+   r,   ulidr"   r
  r  r   time_dump_checkpoint_dump_metadataallrg   r   r   r1   loadr4   r3   r   r   r   setrF   CancelledErrorr/   r   r   r   r   )rL   r   r   r   r$  r%  r   r   rZ   r[   config_checkpoint_idr'  r\   r   r   r   r   r0  next_configr   r"   ulid_objr3  r   r   r   r   r   es      `                         rN   aputzAsyncRedisSaver.aput]  s     6 n-2244!!(HLL,B,BCC $$[11	$((99+//FF $$["55	 -U	UZ^^DRT=U=U  $NN4  	-$	- t$$(<<<#7 &t,M "4I!>!>%8%G%G"%7%F%F"  &!.!. 
O	 !M 
7	7)))))),t}];;H$,$6MM  7 7 7KKK$(IIKK$$6MMM	7 48>F,V444B!;!; ,&';<<<!."33D99 //99# O" AAAA.@AAAAA ;,4X,>)*26*:' "CC N K G=DO#C#C!$/-"@2"EFF (-- !$% .          !O "T_44++,,^[IIIIIIIIII    NNC^     "l6L!k!kOi!k!k+//"4nEEEEEEEEE &+,,-?MMMMMMMMMM    NNG*     % 4	 4	 4	444, &<@F"N"4V"<"<"<B)C)C
  *~~.DEE$. #JNN3I2$N$N O O   "$&*&;&;D&A&A$($7$7"*/3/:  % % ',)' 'O0 &*%D%D.22& &N ( 	1"k..0044*C         
 $(;#7#7E#7#J#J ++NCQQQ&..000000000    D
  	 	 	G	s   =M E  M  %FM FDM !J7 6M 7%KM K.M !L0 /M 0%MM MM S3D?R32S3
S =S?S  SSSr   writesSequence[Tuple[str, Any]]	task_pathc                  K   |sdS |d         d         }|d                              dd          }|d         d         }g }t          |          D ]\  }	\  }
}| j                            |          \  }}t	          |          t          |          t	          |          ||t          j         |
|	          |
||                     |          d	}|                    |           	 t          d |D                       }g }| j
        r |D ]}}|                     |||||d	                   }| j                                                            |d
t          t           |                     d{V  |                    |           ~|rO| j        rHd| j        v r?|                     |d         t'          |          dk    r
|dd         nd           d{V  | j        rg }|D ]6}|                     |||||d	                   }|                    |           7|r| j                            |||          }d t          |          D             }| j                            ||           d{V  | j        rd| j        v rt/          | j                             d          dz            }	 | j                            ||           d{V  dS # t2          $ r! t4                              d|d           Y dS w xY wdS dS dS dS | j                            d          }|D ]r}|                     |||||d	                   }|                                                    |d
t          t           |                     |                    |           sd}|rB|                     |||          }|                                                    |d
ddi           d}| j        rM|rK| j                            |||          }d t          |          D             }|                    ||           |                    d           d{V }d}|D ]E}tA          |t2                    r.tC          |          }d|v sd|"                                v rd}C|F|r|r	 | j                                                             |           d{V }tA          |tF                    rN|                     d          s9d|d<   | j                                                            |d
|           d{V  n# t2          $ r Y nw xY w|r| j        rxd| j        v rot/          | j        d         dz            }|D ]O}	 | j                            ||           d{V  %# t2          $ r t4                              d|           Y Lw xY w|r| j        rzd| j        v rs	 t/          | j        d         dz            }| j                            ||           d{V  dS # t2          $ r! t4                              d|d           Y dS w xY wdS dS dS # tH          j%        $ r  t2          $ r}|d}~ww xY w)aU  Store intermediate writes linked to a checkpoint using Redis JSON.

        This method uses Redis pipeline without transaction to avoid lock contention
        during parallel test execution.

        Args:
            config (RunnableConfig): Configuration of the related checkpoint.
            writes (List[Tuple[str, Any]]): List of writes to store.
            task_id (str): Identifier for the task creating the writes.
            task_path (str): Path of the task creating the writes.

        Raises:
            asyncio.CancelledError: If the operation is cancelled/interrupted
        Nr   rZ   r[   r   r\   )	rZ   r[   r\   rh   rA  ri   channeltypeblobc              3  4   K   | ]}|d          t           v V  dS )r   N)r   )r   ws     rN   r  z.AsyncRedisSaver.aput_writes.<locals>.<genexpr>c  s+      EEadn4EEEEEErO   ri   r/  r   r   r   c                    i | ]\  }}||	S r+  r+  r   ri   rf   s      rN   r   z/AsyncRedisSaver.aput_writes.<locals>.<dictcomp>  s    'W'W'WXS#S'W'W'WrO   r   z-Failed to apply TTL to write registry key: %sT)exc_infoFr   r   c                    i | ]\  }}||	S r+  r+  rI  s      rN   r   z/AsyncRedisSaver.aput_writes.<locals>.<dictcomp>  s    #U#U#UcC#U#U#UrO   )raise_on_errorz
JSON.MERGEmergez/Failed to apply TTL to checkpoint write key: %s)&r   	enumerateserdedumps_typedr+   r,   r   _encode_blobrn   r6  r4   rp   r3   r   r8  r   r   r   r   ra   r5   make_write_keys_zset_keyzaddr   r   r   r   r   r   r   rM  r   r   r/   lowerr   rF   r9  )rL   r   r?  rh   rA  rZ   r[   r\   writes_objectsri   rC  valuetype_rE  	write_objupsert_casecreated_keysrf   r   zset_keyzadd_mappingr   r   r   r   merge_failedresulterr_strr   r=  s                                 rN   aput_writeszAsyncRedisSaver.aput_writes2  s     *  	F>*;7	~.22?BGG~.? %.v%6%6 	- 	-!C!'5*0077KE4/	::!4]!C!C!3M!B!B"&%)'377"))  I !!),,,,l	EEfEEEEEKL  ]!/ - -IGG!%%!%( C +**,,00c4Y;O;OPPPPPPPPP '',,,, ! &8811$Q,/,=,=,A,AQRR((t         %  "!#J%3 / /	"KK%))#%e,  #))#....! "#'#5#N#N%}m$ $
 (X'W:AVAV'W'W'W"k..xFFFFFFFFF  ? 	"}/O/O*-do.A.A-.P.PSU.U*V*VK"&*k&8&8;&O&O O O O O O O O O O#, " " " &$S$,-1 !/ !" !" !" !" !" !""7 "  "" "	" 	"/O/O$  ;//E/BB "0 
- 
-IGG!%%!%( C MMOO''S$sI2F2FGGG '',,,, "$! U%)%D%D!=-& &N MMOO)).#d?STTT % :, :#1JJ!=-   H $V#UY|=T=T#U#U#ULMM(L999 !) 0 0 0 F FFFFFFF  %% ) )F!&)44 )"%f++'722g6P6P+/LL"(L)   N 040@0@0B0B0F0F*1 1 + + + + + + &+T  "1"5"5l"C"C =AOL9"&+"2"2"4"4"8"8 ._# #        %    ! &88"%dom&Dr&I"J"JK+  "&+"4"4S+"F"FFFFFFFFF(   "NN Q #      	 	MT_4T4T&)$/-*H2*M&N&N"k00;GGGGGGGGGGG$   K$%) '      		 	 	 	4T4T % 	 	 	  	 	 	G	s   %G	Y /!K 'K=9Y <K==Y FY BT5 4Y 5
U?Y U6Y 9!VY %W Y WY >X 'Y Y YY Y-&Y((Y-c                    t          j        |                     |||          | j                                                  S )aZ  Synchronous wrapper for aput_writes.

        Args:
            config (RunnableConfig): Configuration of the related checkpoint.
            writes (List[Tuple[str, Any]]): List of writes to store.
            task_id (str): Identifier for the task creating the writes.
            task_path (str): Path of the task creating the writes.
        )rF   run_coroutine_threadsafer`  rH   r^  )rL   r   r?  rh   rA  s        rN   
put_writeszAsyncRedisSaver.put_writes  s;     /VVW55ty
 

&((	rO   Dict[str, Any]c                   	 t          j                    | j        u rt          j        d          n# t          $ r Y nw xY wt          j        |                     |||          | j                                                  S )zTRetrieve channel_values using efficient FT.SEARCH with checkpoint_id (sync wrapper).zSynchronous calls to AsyncRedisSaver are only allowed from a different thread. From the main thread, use the async interface.For example, use `await checkpointer.get_channel_values(...)`.)rF   rG   rH   InvalidStateErrorRuntimeErrorrb  r   r^  )rL   rZ   r[   r\   s       rN   get_channel_valuesz"AsyncRedisSaver.get_channel_values"  s    	'))TY66/U   7  	 	 	D	/$$ 
 I
 
 &((	   .1 
>>c                    	 t          j                    | j        u rt          j        d          n# t          $ r Y nw xY wt          j        |                     |          | j                                                  S )ay  Get a checkpoint tuple from Redis.

        Args:
            config (RunnableConfig): The config to use for retrieving the checkpoint.

        Returns:
            Optional[CheckpointTuple]: The retrieved checkpoint tuple, or None if no matching checkpoint was found.

        Raises:
            asyncio.InvalidStateError: If called from the wrong thread/event loop
        zSynchronous calls to AsyncRedisSaver are only allowed from a different thread. From the main thread, use the async interface.For example, use `await checkpointer.aget_tuple(...)` or `await graph.ainvoke(...)`.)rF   rG   rH   rf  rg  rb  r   r^  )rL   r   s     rN   	get_tuplezAsyncRedisSaver.get_tuple8  s    
	'))TY66/+   7  	 	 	D	/OOF##TY
 

&((	ri  c                   	 t          j                    | j        u rt          j        d          n# t          $ r Y nw xY wt          j        |                     ||||          | j                                                  S )a7  Store a checkpoint to Redis.

        Args:
            config (RunnableConfig): The config to associate with the checkpoint.
            checkpoint (Checkpoint): The checkpoint to save.
            metadata (CheckpointMetadata): Additional metadata to save with the checkpoint.
            new_versions (ChannelVersions): New channel versions as of this write.

        Returns:
            RunnableConfig: Updated configuration after storing the checkpoint.

        Raises:
            asyncio.InvalidStateError: If called from the wrong thread/event loop
        zSynchronous calls to AsyncRedisSaver are only allowed from a different thread. From the main thread, use the async interface.For example, use `await checkpointer.aput(...)` or `await graph.ainvoke(...)`.)rF   rG   rH   rf  rg  rb  r>  r^  )rL   r   r   r   r$  s        rN   putzAsyncRedisSaver.putS  s    *
	'))TY66/+   7  	 	 	D	/IIfj(LAA49
 

&((	ri  AsyncIterator[AsyncRedisSaver]c                 K    | ||||||          4 d {V 	 }|W V  d d d           d {V  d S # 1 d {V swxY w Y   d S )NrB   r+  )clsr;   r6   r7   r8   r9   r:   savers           rN   from_conn_stringz AsyncRedisSaver.from_conn_stringw  s       3%+/$;
 
 
 	 	 	 	 	 	 	 	 KKKK	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   4
>>r   c                8  K   t          |          }t          |          }t          |          }|                     |||          }| j                                                            |d           d{V }	|	si S |	d         }
|
                    di           S )zERetrieve channel_values using efficient FT.SEARCH with checkpoint_id.r   Nr   r   )r+   r,   rg   r3   r   r   )rL   rZ   r[   r\   r   r   r   r   r   r   r   s              rN   r   z#AsyncRedisSaver.aget_channel_values  s       "4I!>!>%8%G%G"%7%F%F" ??
 
 !% 0 0 2 2 6 6~~ V VVVVVVV 	I %Q'
~~.333rO   r   #List[Tuple[str, Union[str, bytes]]]c                *  K   |sg S | j         r	 | j                             |||           d{V }|dk    rg S | j                             |||           d{V }g }|D ]$}t          |v sd|v r|                    |           %|sg S | j                            d          }|D ])}|                                                    |           *|	                                 d{V }	g }
|	D ]}|r|                    d          t          k    r~|
                    |                    dd          |                    d	d          |                    d
d          |                    dd          |                    dd          f           |

                    d            d |
D             S # t          $ r Y nw xY wt          t          d          t          |          k    t          d          t          |          k    z  t          d          t          |          k    z  t          d          t          k    z  g dd          }| j                            |           d{V }t%          |j        d           }fd|D             S )a3  Load pending sends for a parent checkpoint.

        Args:
            thread_id: The thread ID
            checkpoint_ns: The checkpoint namespace
            parent_checkpoint_id: The ID of the parent checkpoint

        Returns:
            List of (type, blob) tuples representing pending sends
        Nr   __pregel_tasksFr   rC  rA  r   rh   ri   rD  rE  rO   c                0    | d         | d         | d         fS )Nr   r   r   r+  xs    rN   <lambda>z6AsyncRedisSaver._aload_pending_sends.<locals>.<lambda>  s    1qtQqT@R rO   rf   c                .    g | ]}|d          |d         fS )      r+  )r   items     rN   
<listcomp>z8AsyncRedisSaver._aload_pending_sends.<locals>.<listcomp>  s%    TTTta$q'*TTTrO   rZ   r[   r\   )rD  $.blobrA  rh   ri   d   r   r   r   c                f    t          | dd          t          | dd          t          | dd          fS NrA  r   rh   ri   r   r~   ds    rN   rz  z6AsyncRedisSaver._aload_pending_sends.<locals>.<lambda>  s6    ;++9b))5!$$ rO   c                    g | ]?}t          |d t          |dd                    x$|j                                        f@S )r  rE  N)r~   rD  encode)r   r  rE  s     rN   r  z8AsyncRedisSaver._aload_pending_sends.<locals>.<listcomp>  sU     
 
 
8WQ-E-EFFFS V]]__d#SSSrO   )r5   get_write_countr   r   rn   r3   r   r   r   r   sortr   r   r   r+   r,   r2   r  sortedr  )rL   rZ   r[   r   write_countr   task_write_keysrf   r   r   pending_sends_with_sort_keys
write_dataparent_writes_queryresr  rE  s                  @rN   r   z$AsyncRedisSaver._aload_pending_sends  s|      $ 	I  9	8$($6$F$F}.B% %       !##I $(#5#D#D}.B$ $      

 #%% 4 4C ||'73'>'>'..s333& I  ;//E/BB* - -CMMOO'',,,, ( 0 0 2 2222222 02,") 
 
J! 	jnnY&?&?5&H&H4;; *{B ? ? *y" = = *ua 8 8 *vr : : *vs ; ;   -116R6R1SSS UT7STTTT   
 *[!!%7	%B%BB''+>}+M+MMO''+=>R+S+SSU y>>U*,
 LKK	
 	
 	
 0778KLLLLLLLL H 
 
 

 
 
 

 
 
 	
s   )F3 AF3 
D(F3 3
G ?G List[PendingWrite]c                  K   |g S | j         re	 | j                             |||           d {V }|dk    rg S | j                             |||           d {V }| j                            d          }|D ])}|                                                    |           *|                                 d {V }i }	|D ]}
|
r|
                    dd          }t          |
                    dd                    }|||
                    dd          |
                    dd          |
                    d	d
          d|	||f<   t          j
        | j        |	          }|S # t          $ r Y nw xY wt          t          d          t          |          k    t          d          t!          |          k    z  t          d          t          |          k    z  g dd          }| j                            |           d {V }t'          |j        d           }i }|D ]}t          t+          |dd                    }t          t+          |dd                    }t+          |dd          }t-          |t                    r|                    d          }||t          t+          |dd                    t          t+          |dd                    |d|||f<   t          j
        | j        |          }|S )Nr   Fr   rh   r   ri   rC  rD  rE  rO   rh   ri   rC  rD  rE  rZ   r[   r\   )rh   ri   rC  rD  r  rC   r  c                $    t          | dd          S )Nri   r   r  rx  s    rN   rz  z7AsyncRedisSaver._aload_pending_writes.<locals>.<lambda>Y  s    '!UTUBVBV rO   r{  r  zutf-8)r5   r  r   r3   r   r   r   r   r/   r&   _load_writesrO  r   r   r   r+   r,   r2   r  r  r  r~   r   r  )rL   rZ   r[   r\   r  r   r   rf   r   writes_dictr  rh   ri   r   writes_querywrites_resultssorted_writessearch_writes_dictr   	blob_datas                       rN   r   z%AsyncRedisSaver._aload_pending_writes  s       I  ,	+$($6$F$F}m% %       !##I $(#5#D#D}m$ $      

  ;//E/BB% - -CMMOO'',,,, ( 0 0 2 2222222 FH") 
 
J! 	",..B"?"?!*..":":;;'.#&'1~~i'D'D$.NN62$>$>$.NN63$?$?7 7WcN3 "0!<TZ!U!U%%    #";//3Ei3P3PP?##':='I'IIK?##'9-'H'HHJ JII
 
 
  $;BB<PPPPPPPP ~28V8VWWW EG  	 	C'#y"5566Ggc5!,,--CXr22I)S)) 6%,,W55	"wsIr::;;GC4455!2 2~.. (4TZASTTs   )E$ D)E$ $
E10E1
batch_keysList[Tuple[str, str, str]]?Dict[Tuple[str, str, str], List[Tuple[str, Union[str, bytes]]]]c                4  K   |si S i }i }|D ].\  }}}||f}||vrg ||<   ||                              |           /|                                D ]F\  \  }}}t          |          }	t          |          }
d |D             }t	          d          |	k    }t	          d          |
k    }t	          d          t
          k    }t	          d          |k    }t          ||z  |z  |z  g dd          }| j                            |           d	{V }i }|j	        D ]:}t          |j                  }||vrg ||<   ||                              |           ;|D ]>}|||f}|                    |g           }t          |d
           }d |D             ||<   ?H|S )zBatch load pending sends for multiple parent checkpoints.

        Args:
            batch_keys: List of (thread_id, checkpoint_ns, parent_checkpoint_id) tuples

        Returns:
            Dict mapping batch_key -> list of (type, blob) tuples
        c                ,    g | ]}t          |          S r+  r+   )r   pids     rN   r  z>AsyncRedisSaver._abatch_load_pending_sends.<locals>.<listcomp>  s.     2 2 2,/"3''2 2 2rO   rZ   r[   rC  r\   )r\   rD  r  rA  rh   ri   rC   r  Nc                f    t          | dd          t          | dd          t          | dd          fS r  r  rx  s    rN   rz  z<AsyncRedisSaver._abatch_load_pending_sends.<locals>.<lambda>  s6    ;339b115!,,# rO   r{  c                p    g | ]3}t          |d d          t          |dt          |dd                    f4S )rD  r   r  rE  rO   r  )r   r   s     rN   r  z>AsyncRedisSaver._abatch_load_pending_sends.<locals>.<listcomp>  sV     * * *
   VR00XwsFC/H/HII* * *rO   )rn   r   r+   r,   r   r   r   r2   r  r  r)   r\   r   r  )rL   r  results_mapgrouped_keysrZ   r[   r   	group_keyparent_checkpoint_idsr   r   "storage_safe_parent_checkpoint_idsthread_filter	ns_filterchannel_filtercheckpoint_filterbatch_querybatch_resultswrites_by_checkpointr   r  r?  r  s                          rN   r  z*AsyncRedisSaver._abatch_load_pending_sendso  s       	I :<>H 	A 	A:I}&:"M2I,,*,Y'#**+?@@@@ BNASASAUAU B	 B	=&Y(=%7	%B%B")<])K)K&2 23H2 2 2.
  ,,0FFMO,,0JJI ^^u4N O$$(JJ  &"/###$ !#!   !  K  #'">"E"Ek"R"RRRRRRRM :< $) G G';C<M'N'N$'/CCCAC()=>$%9:AA#FFFF )>  $&7KL	-112FKK !' ! ! !* *
  -* * *I&&!0 rO   .Dict[Tuple[str, str, str], List[PendingWrite]]c                T	  K   |si S i }| j         r| j                            d          }|D ]7\  }}}| j                             |||          }|                    |           8|                                 d{V }| j                            d          }g }	t          |          D ]k\  }
\  }}}||
         dk    rL|	                    |||f           | j                             |||          }|                    |dd           a|||f}g ||<   l|	r|                                 d{V }| j                            d          }i }d}t          |	          D ]Y\  }
\  }}}||
         }|rFd |D             }|D ]7}|	                                
                    |           ||||f||<   |dz  }8Z|dk    r|                                 d{V }i }t          |          D ]\  }}|r||         \  }}}}|||f}||vri ||<   |
                    dd	          }t          |
                    d
d                    }|||
                    dd	          |
                    dd	          |
                    dd          d||         ||f<   |                                D ]"\  }}t          j        | j        |          ||<   #ni }|D ].\  }}}||f}||vrg ||<   ||                             |           /|                                D ]\  \  }}}t!          |          }t#          |          }d |D             }t%          d          |k    }t%          d          |k    } t%          d          |k    }!t'          || z  |!z  g dd          }"| j                            |"           d{V }#i }$|#j        D ]}%t/          |%j                  }||$vri |$|<   t3          |%dd	          }t          t3          |%d
d                    }&t3          |%dt3          |%dd                    }'||&t3          |%dd	          t3          |%dd	          |'d|$|         ||&f<   |D ]:}|||f}|$
                    |i           }t          j        | j        |          ||<   ;|S )zBatch load pending writes for multiple checkpoints.

        Args:
            batch_keys: List of (thread_id, checkpoint_ns, checkpoint_id) tuples

        Returns:
            Dict mapping batch_key -> list of PendingWrite objects
        Fr   Nr   r   c                d    g | ]-}t          |t                    r|                                n|.S r+  )r   bytesdecode)r   rf   s     rN   r  z?AsyncRedisSaver._abatch_load_pending_writes.<locals>.<listcomp>  sC     ( ( ( # -7sE,B,BKCJJLLL( ( (rO   r   rh   r   ri   rC  rD  rE  rO   r  c                ,    g | ]}t          |          S r+  r  )r   cids     rN   r  z?AsyncRedisSaver._abatch_load_pending_writes.<locals>.<listcomp>K  s.     / / /03&s++/ / /rO   rZ   r[   r\   )r\   rh   ri   rC  rD  r  i  r  r  )r5   r3   r   rR  zcardr   rN  rn   zranger   r   r/   r   r&   r  rO  r+   r,   r   r   r2   r  r  r)   r\   r~   )(rL   r  r  r   rZ   r[   r\   r[  write_countscheckpoints_with_writesir  all_write_keys_resultswrite_key_mappingpipeline_indexr   decoded_keysrf   all_writes_datar  ri   r  rh   idx_valr  r  r  checkpoint_idsr   r   storage_safe_checkpoint_idsr  r  r  r  r  fallback_writes_by_checkpointr   idx_strrE  s(                                           rN   r  z+AsyncRedisSaver._abatch_load_pending_writes  sv       	IFH  _	{+++>>H <F ) )7	=--FF}m  x(((( "*!1!1!3!3333333L {+++>>H&(#@I*@U@U 0 0<<I}m?Q&&+22"M=A    $1JJ!=-   H OOHa4444 "+M= II-/K	**& =/7/?/?/A/A)A)A)A)A)A)A&  ;//E/BB$&!!"DM+E E 0 0@A@	=- "8!:J! 0( ('1( ( ( $0 0 0C$MMOO//444 ) - - #	A-n= +a/NN "A%%,4,<,<,>,>&>&>&>&>&>&>O
  ) ,5_+E+E  Z%  1# 6 II}mS *3M=(QI(0DDDBD 4Y ?&0nnY&C&CG&)*..*B*B&C&CG+2'.+5>>)R+H+H(2vr(B(B(2vs(C(CS S0;Wg<NO 3G2L2L2N2N  .	;1?1L J2 2I.. >@L;E > >7	=-&6	L00.0L+Y'..}==== ?K>P>P>R>R 6 6:*MN);I)F)F&-@-O-O*/ /7E/ / /+
 !$K 0 04J J004NN	$'$8$8<W$W!)&3i&?BS&S# # # !%   '+&B&I&I+&V&V V V V V V V
  . )-  C$89J$K$KM$,IIIGI5mD%c9b99G!'#ua"8"899G"3'#vs2K2KLLD $+&#*3	2#>#> 'VR 8 8 $X X1-@'7ASTT &4  M!*M= II"?"C"CMSU"V"VK-;-H
K. .K	** rO   c                  K   t          |          }t          t          d          |k    ddgd          }| j                            |           d{V }g }t                      }|j        D ]e}t          |dd          }t          |dd          }	|                    |           | 	                    |||	          }
|
                    |
           f|D ],}d| d	t          |           }|
                    |           -t          t          d          |k    g d
d          }| j                            |           d{V }|j        D ]t}t          |dd          }t          |dd          }	t          |dd          }t          |dd          }|                     |||	||          }|
                    |           u| j        rt                      }|j        D ]s}t          |dd          }t          |dd          }	|||	f}
|
|vrF|                    |
           | j                            |||	          }|
                    |           t| j        r'|D ]"}| j                            |           d{V  #dS | j                                        }|D ]}|                    |           |                                 d{V  dS )zDelete all checkpoints and writes associated with a specific thread ID.

        Args:
            thread_id: The thread ID whose checkpoints should be deleted.
        rZ   r[   r\   rl   r  Nr   r   r^   r[   r\   rh   ri   rh   ri   r   )r+   r   r   r1   r  r8  r  r~   addr   rn   r,   r2   !_make_redis_checkpoint_writes_keyr5   rR  r4   r3   deleter   r   )rL   rZ   r   checkpoint_querycheckpoint_resultskeys_to_deletecheckpoint_namespacesr   r[   r\   r   r   r  r  rh   ri   	write_keyprocessed_checkpointsr[  rf   r   s                        rN   adelete_threadzAsyncRedisSaver.adelete_thread  s      "4I!>!> '!+..2HH*O<
 
 
 $(#9#@#@AQ#R#RRRRRRR  #%* 	2 	2C#C"==M#C"==M "%%m444 "<<&} N !!.1111 3 	6 	6M!s6L!s!sObcpOqOq!s!s!!"45555
 #!+..2HHNNN
 
 
  $;BB<PPPPPPPP!& 		- 		-C#C"==M#C"==Mc9b11G#ua((C>>&}gs I !!),,,,  	4$'EE!). 4 4 '_b A A '_b A A"+]M!J!)>>>)--n===#1JJ!=-   H #))(333  		%% . .k((----------. . {++--H% % %$$$$""$$$$$$$$$$$rO   keep_latestrl   )strategy	keep_lastmax_results
thread_idsSequence[str]r  r  r  r   c               &  K   ||dk    rd}nd}|st          d          |dk     rt          d|           |dk     rt          d|           |D ]<}t          |          }t          t          d          |k    d	d
g|          }| j                            |           d{V }|j        s_t          t                    }	|j        D ].}
t          |
d	d          }|	|         
                    |
           /g }t                      }|	                                D ]l\  }}t          |d d          }||d         }|                    |           t          |          t          |          k    r|                    |           m|s>g }|D ]]}
t          |
d	d          }t          |
d
d          }|
                    |                     |||                     t          t          d          |k    t          d
          |k    z  g d|          }| j                            |           d{V }|j        D ]w}|
                    |                     |t          |d	d          t          |d
d          t          |dd          t)          t          |dd                                         x| j        r/|
                    | j                            |||                     _|D ]}|
                    d| d|            | j        r'|D ]"}| j                            |           d{V  #| j                                        }|D ]}|                    |           |                                 d{V  >dS )u  Prune old checkpoints for the given threads per namespace.

        Retains the most-recent checkpoints **per checkpoint namespace** and
        removes the rest, along with their associated write keys and
        key-registry sorted sets.

        Each namespace (root ``""`` and any subgraph namespaces) is treated as
        an independent checkpoint chain.  Channel values are stored inline
        within each checkpoint document, so they are automatically removed
        when the checkpoint document is deleted.

        Args:
            thread_ids: Thread IDs whose old checkpoints should be pruned.
            strategy: Pruning strategy.  ``"keep_latest"`` retains only the
                most recent checkpoint per namespace (default).  ``"delete"``
                removes all checkpoints for the thread.
            keep_last: Optional override — number of recent checkpoints to
                retain per namespace.  When provided, takes precedence over
                ``strategy``.  Use ``keep_last=0`` to remove all checkpoints.
            max_results: Maximum number of checkpoints fetched from the index
                per thread in a single query.  Defaults to 10 000.
        Nr  r   r   z+``thread_ids`` must be a non-empty sequencez ``keep_last`` must be >= 0, got z"``max_results`` must be >= 1, got rZ   r[   r\   r  r   c                $    t          | dd          S )Nr\   r   r  r  s    rN   rz  z(AsyncRedisSaver.aprune.<locals>.<lambda>'  s    '!_b"A"A rO   T)rf   reverser  rh   ri   r   r^   )r	  r+   r   r   r1   r  r  r   r  r~   rn   r8  r   r  extendra   r  r   r2   r  r   r5   rR  r4   r3   r  r   r   )rL   r  r  r  r  rZ   r   r  r  by_nsr   nsto_evictfully_evicted_nsns_docs	ns_sorted
ns_evictedr  r[   r\   r  r  wdocrf   r   s                            rN   aprunezAsyncRedisSaver.aprune  s     > 8##			  	LJKKKq==K	KKLLL??O+OOPPP# ^	) ^	)I%7	%B%B"  +"%k"2"26L"L.@'     
 (,'='D'DEU'V'V!V!V!V!V!V!V%*  &1%6%6E). & &S/266b	  %%%% H$'EE${{}} 	- 	-G"AA   	
 'yzz2

+++z??c'll22$((,,, N & & '_b A A '_b A A %%33.}     +[))-CC//=@B #W"V"V +      (,'C'J'J<'X'X!X!X!X!X!X!X*/ 	 	D"))>>2#D/2>>#D/2>>#D)R88eQ 7 788     % "))*CC%}m    '  %%F)?FF"FF      )) 2 2C+,,S11111111112  ;//11) ) )COOC((((&&((((((((((}^	) ^	)rO   r*  )r;   r<   r6   r=   r7   r>   r8   r>   r9   r/   r:   r/   r?   r@   )NNN)r;   r<   r6   r=   r7   r>   r?   r@   )r?   r@   )rZ   r/   r[   r/   r\   r/   r?   r/   )rZ   r/   r[   r/   r\   r/   rh   r/   ri   rj   r?   r/   )r?   r.   )ru   rv   rw   rx   ry   rz   r?   r@   )NN)r   r/   r   r   r   r   r?   r   )r   r   r?   r   )
r   r   r   r   r   r   r   rj   r?   r   )r  )r   r   r   r   r   r   r$  r   r%  r/   r?   r   )r   )
r   r   r?  r@  rh   r/   rA  r/   r?   r@   )r   r   )rZ   r/   r[   r/   r\   r/   r?   rd  )
r   r   r   r   r   r   r$  r   r?   r   )r;   r<   r6   r=   r7   r>   r8   r>   r9   r/   r:   r/   r?   rn  )r   r   N)
rZ   r/   r[   r/   r\   r/   r   r>   r?   rd  )rZ   r/   r[   r/   r   r/   r?   rt  )rZ   r/   r[   r/   r\   r/   r?   r  )r  r  r?   r  )r  r  r?   r  )rZ   r/   r?   r@   )
r  r  r  r/   r  rj   r  r   r?   r@   )'__name__
__module____qualname____doc____annotations__r4   r5   r#   r$   rE   rS   rY   rg   rp   rt   r   rr   r   r   r   r   r#  r>  r`  rc  rh  rk  rm  classmethodr   rr  r   r   r   r  r  r  r  __classcell__)rM   s   @rN   r.   r.   @   s          OOO''''----    $(L''''04M4444 $(. HL48(,!2'>. . . . . . . .8 $(GK48	' ' ' ' '(
 
 
 
   @( ( ( (T   > > > >(
; 
; 
; 
;   & & & && -1'+	1 1 1 1 1fO
 O
 O
 O
j ,0+/#x x x x x x@ $S S S S St [ [ [ [ [D     ( MO    ,   6" " " "H  $( HL48(,!2'>      [.  594 4 4 4 4< TVh
 h
 h
 h
 h
Z  	Y Y Y Y Yv] ] ] ]~r r r rhX% X% X% X%| &#' K) K) K) K) K) K) K) K) K) K)rO   r.   )Gr  
__future__r   rF   r   loggingcollectionsr   
contextlibr   typesr   typingr   r   r	   r
   r   r   r   r   r   r   r  langchain_core.runnablesr   langgraph.checkpoint.baser   r   r   r   r   r   r   langgraph.constantsr   redis.asyncior   
AsyncRedisredis.asyncio.clusterr   r   redisvl.indexr   redisvl.queryr   redisvl.query.filterr   r   redisvl.redis.connectionr    r2  r"   langgraph.checkpoint.redis.baser#   r$   r%   r&   'langgraph.checkpoint.redis.key_registryr'   r   langgraph.checkpoint.redis.utilr(   r)   r*   r+   r,   	getLoggerr  r   r.   r+  rO   rN   <module>r     s   5 5 " " " " " "    # # # # # # * * * * * *                               3 3 3 3 3 3                  & % % % % % - - - - - - C C C C C C * * * * * * % % % % % % ) ) ) ) ) ) ) ) ; ; ; ; ; ;                                    
	8	$	$g ) g ) g ) g ) g )5%6679IIJg ) g ) g ) g ) g )rO   