
    k
i{                     n    d Z ddlmZ dZdZdedefdZdedefdZdedefd	Zdedefd
Z	dedefdZ
dS )a5  
RediSearch versions below 2.10 don't support indexing and querying
empty strings, so we use a sentinel value to represent empty strings.
Because checkpoint queries are sorted by checkpoint_id, we use a UUID
that is lexicographically sortable. Typically, checkpoints that need
sentinel values are from the first run of the graph, so this should
generally be correct.

This module also includes utility functions for safely handling Redis responses,
including handling bytes vs string responses depending on how the Redis client is
configured with decode_responses.
    )Any	__empty__z$00000000-0000-0000-0000-000000000000valuereturnc                 :    | dk    rt           S t          |           S )z
    Prepare a value for storage in Redis as a string.

    Convert an empty string to a sentinel value, otherwise return the
    value as a string.

    Args:
        value (str): The value to convert.

    Returns:
        str: The converted value.
     )EMPTY_STRING_SENTINELstrr   s    C:\Users\Dell Inspiron 16\Desktop\tws\AgrotaPowerBi\back-agrota-powerbi\mcp-client-agrota\venv\Lib\site-packages\langgraph/checkpoint/redis/util.pyto_storage_safe_strr      s     {{$$5zz    c                      | t           k    rdS | S )z
    Convert a value from a sentinel value to an empty string if present,
    otherwise return the value unchanged.

    Args:
        value (str): The value to convert.

    Returns:
        str: The converted value.
    r   )r	   r   s    r   from_storage_safe_strr   '   s     %%%rr   c                 :    | dk    rt           S t          |           S )a  
    Prepare a value for storage in Redis as an ID.

    Convert an empty string to a sentinel value for empty ID strings, otherwise
    return the value as a string.

    Args:
        value (str): The value to convert.

    Returns:
        str: The converted value.
    r   )EMPTY_ID_SENTINELr
   r   s    r   to_storage_safe_idr   8   s     {{  5zzr   c                      | t           k    rdS | S )z
    Convert a value from a sentinel value for empty ID strings to an empty
    ID string if present, otherwise return the value unchanged.

    Args:
        value (str): The value to convert.

    Returns:
        str: The converted value.
    r   )r   r   s    r   from_storage_safe_idr   K   s     !!!rr   objc                    | dS t          | t                    r(	 |                     d          S # t          $ r | cY S w xY wt          | t                    r| S t          | t
                    rd |                                 D             S t          | t                    rd | D             S t          | t                    rt          d | D                       S t          | t                    rd | D             S | S )ax  
    Safely decode Redis responses, handling both string and bytes types.

    This is especially useful when working with Redis clients configured with
    different decode_responses settings. It recursively processes nested
    data structures (dicts, lists, tuples, sets).

    Based on RedisVL's convert_bytes function (redisvl.redis.utils.convert_bytes)
    but implemented directly to avoid runtime import issues and ensure consistent
    behavior with sets and other data structures. See PR #34 and referenced
    implementation: https://github.com/redis/redis-vl-python/blob/9f22a9ad4c2166af6462b007833b456448714dd9/redisvl/redis/utils.py#L20

    Args:
        obj: The object to decode. Can be a string, bytes, or a nested structure
            containing strings/bytes (dict, list, tuple, set).

    Returns:
        The decoded object with all bytes converted to strings.
    Nzutf-8c                 N    i | ]"\  }}t          |          t          |          #S  safely_decode).0kvs      r   
<dictcomp>z!safely_decode.<locals>.<dictcomp>{   s.    KKKtq!a  -"2"2KKKr   c                 ,    g | ]}t          |          S r   r   r   items     r   
<listcomp>z!safely_decode.<locals>.<listcomp>}        444d##444r   c              3   4   K   | ]}t          |          V  d S )Nr   r!   s     r   	<genexpr>z safely_decode.<locals>.<genexpr>   s*      99T]4((999999r   c                 ,    h | ]}t          |          S r   r   r!   s     r   	<setcomp>z safely_decode.<locals>.<setcomp>   r$   r   )

isinstancebytesdecodeUnicodeDecodeErrorr
   dictitemslisttupleset)r   s    r   r   r   \   s$   ( {t	C		 	::g&&&! 	 	 	JJJ	 
C		 
	C		 
KKsyy{{KKKK	C		 444444	C		 99S999999	C		 444444 
s   0 ??N)__doc__typingr   r	   r   r
   r   r   r   r   r   r   r   r   <module>r4      s          # : s s    &     "c c    &     "(s (s ( ( ( ( ( (r   