§
    ~Štjb  ã                  ó  — d Z 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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mZmZmZmZ er	  ej        d
¦  «        ZdZdZdZe G d„ d¦  «        ¦   «         Ze G d„ d¦  «        ¦   «         Z G d„ de
¦  «        Z  G d„ de ¦  «        Z! G d„ de ¦  «        Z" e!¦   «         Z# e"¦   «         Z$eeedœd(d!„Z%eeedœd(d"„Z&d)d#„Z' G d$„ d%e!¦  «        Z( G d&„ d'e"¦  «        Z)dS )*z°Prompt caching module for LangSmith SDK.

This module provides thread-safe LRU caches with background refresh
for prompt caching. Includes both sync and async implementations.
é    )ÚannotationsN)ÚABC)ÚOrderedDict)Ú	Awaitable)Ú	dataclass)ÚPath)ÚTYPE_CHECKINGÚAnyÚCallableÚOptionalÚUnionzlangsmith.cachei,  éd   é<   c                  ó>   — e Zd ZU dZded<   ded<   dZded<   dd„ZdS )Ú
CacheEntryz4A single cache entry with metadata for TTL tracking.r
   ÚvalueÚfloatÚ
created_atNzOptional[Callable[[], Any]]Úrefresh_funcÚttl_secondsúOptional[float]ÚreturnÚboolc                óH   — |€dS t          j         ¦   «         | j        z
  |k    S )z/Check if entry is past its TTL (needs refresh).NF)Útimer   )Úselfr   s     úT/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/langsmith/prompt_cache.pyÚis_stalezCacheEntry.is_stale)   s%   € àÐØ�5Ý”	‘”˜dœoÑ-°Ò<Ð<ó    )r   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú__annotations__r   r   © r   r   r   r   !   sV   € € € € € € à>Ð>à€J€J�JØÐÐÑØ04€LÐ4Ð4Ð4Ñ4ð=ð =ð =ð =ð =ð =r   r   c                  ó|   — e Zd ZU dZdZded<   dZded<   dZded<   dZded<   e	dd	„¦   «         Z
e	dd„¦   «         ZdS )ÚCacheMetricszCache performance metrics.r   ÚintÚhitsÚmissesÚ	refreshesÚrefresh_errorsr   c                ó    — | j         | j        z   S )z%Total cache requests (hits + misses).)r)   r*   ©r   s    r   Útotal_requestszCacheMetrics.total_requests9   s   € ð Œy˜4œ;Ñ&Ð&r   r   c                ó4   — | j         }|dk    r
| j        |z  ndS )zCache hit rate (0.0 to 1.0).r   g        )r/   r)   )r   Útotals     r   Úhit_ratezCacheMetrics.hit_rate>   s&   € ð Ô#ˆØ$)¨A¢I IˆtŒy˜5Ñ Ð °3Ð6r   N)r   r(   )r   r   )r    r!   r"   r#   r)   r$   r*   r+   r,   Úpropertyr/   r2   r%   r   r   r'   r'   0   s–   € € € € € € à$Ð$à€D€M€M€M�MØ€F€O€O€O�OØ€IÐÐÐÑØ€NÐÐÐÑàð'ð 'ð 'ñ „Xð'ð ð7ð 7ð 7ñ „Xð7ð 7ð 7r   r'   c                  óŠ   — e Zd ZdZg d¢Zeeefd"d„Ze	d#d„¦   «         Z
d$d„Zd%d„Zd&d„Zd'd„Zd$d„Zd(d„Zd)d„Zd*d„Zd"d „Zd!S )+Ú_BasePromptCachez­Base class for prompt caches with shared LRU logic.

    Provides thread-safe in-memory LRU cache operations.
    Subclasses implement the background refresh mechanism.
    )Ú_cacheÚ_lockÚ	_max_sizeÚ_ttl_secondsÚ_refresh_intervalÚ_metricsÚmax_sizer(   r   r   Úrefresh_interval_secondsr   r   ÚNonec                ó²   — t          ¦   «         | _        t          j        ¦   «         | _        t          ¦   «         | _        |                      |||¬¦  «         dS )ag  Initialize the base cache.

        Args:
            max_size: Maximum entries in cache (LRU eviction when exceeded).
            ttl_seconds: Time before entry is considered stale. Set to None for
                infinite TTL (entries never expire, no background refresh).
            refresh_interval_seconds: How often to check for stale entries.
        ©r<   r   r=   N)r   r6   Ú	threadingÚRLockr7   r'   r;   Ú
_configure©r   r<   r   r=   s       r   Ú__init__z_BasePromptCache.__init__U   sX   € õ 5@±M´MˆŒÝ”_Ñ&Ô&ˆŒ
Ý$™œˆŒØ�ŠØØ#Ø%=ð 	ñ 	
ô 	
ð 	
ð 	
ð 	
r   r'   c                ó   — | j         S )zGet cache performance metrics.)r;   r.   s    r   Úmetricsz_BasePromptCache.metricsl   s   € ð Œ}Ðr   c                ó,   — t          ¦   «         | _        dS )zReset all metrics to zero.N)r'   r;   r.   s    r   Úreset_metricsz_BasePromptCache.reset_metricsq   s   € å$™œˆŒˆˆr   ÚkeyÚstrr   úCallable[[], Any]úOptional[Any]c                óJ  — | j         dk    rdS | j        5  || j        vr#| j        xj        dz  c_        	 ddd¦  «         dS | j        |         }||_        | j                             |¦  «         | j        xj        dz  c_        |j        cddd¦  «         S # 1 swxY w Y   dS )a]  Get a value from cache.

        Args:
            key: The cache key (prompt identifier like "owner/name:hash").
            refresh_func: Function to refresh this cache entry when stale.

        Returns:
            The cached value or None if not found.
            Stale entries are still returned (background refresh handles updates).
        r   Né   )	r8   r7   r6   r;   r*   r   Úmove_to_endr)   r   )r   rJ   r   Úentrys       r   Úgetz_BasePromptCache.getu   s  € ð Œ>˜QÒÐØ�4àŒZð 	ð 	Ø˜$œ+Ð%Ð%Ø”Ð$Ô$¨Ñ)Ð$Ô$Øð	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð
 ”K Ô$ˆEð ".ˆEÔð ŒK×#Ò# CÑ(Ô(Ð(àŒMÐÔ !Ñ#ÐÔØ”;ð	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s   • BÁA	BÂBÂBr   r
   c                óî  — | j         dk    rdS | j        5  t          j        ¦   «         }t          |||¬¦  «        }|| j        vrut          | j        ¦  «        | j         k    rXt          t          | j        ¦  «        ¦  «        }| j                             |¦  «         t           
                    d|› �¦  «         || j        |<   | j                             |¦  «         ddd¦  «         dS # 1 swxY w Y   dS )ú×Set a value in the cache.

        Args:
            key: The cache key (prompt identifier).
            value: The value to cache.
            refresh_func: Function to refresh this cache entry when stale.
        r   N)r   r   r   zEvicted oldest cache entry: )r8   r7   r   r   r6   ÚlenÚnextÚiterÚpopÚloggerÚdebugrP   )r   rJ   r   r   ÚnowrQ   Ú
oldest_keys          r   Ú_setz_BasePromptCache._set”   s.  € ð Œ>˜QÒÐØˆFàŒZð 	)ð 	)Ý”)‘+”+ˆCÝ U°sÈÐVÑVÔVˆEð ˜$œ+Ð%Ð%­#¨d¬kÑ*:Ô*:¸d¼nÒ*LÐ*Lå!¥$ t¤{Ñ"3Ô"3Ñ4Ô4�
Ø”—’ 
Ñ+Ô+Ð+Ý—’ÐH¸JÐHÐHÑIÔIÐIà$ˆDŒK˜ÑØŒK×#Ò# CÑ(Ô(Ð(ð	)ð 	)ð 	)ñ 	)ô 	)ð 	)ð 	)ð 	)ð 	)ð 	)ð 	)ð 	)øøøð 	)ð 	)ð 	)ð 	)ð 	)ð 	)s   •CC*Ã*C.Ã1C.c                ó|   — | j         5  | j                             |d¦  «         ddd¦  «         dS # 1 swxY w Y   dS )ziRemove a specific entry from cache.

        Args:
            key: The cache key to invalidate.
        N)r7   r6   rX   )r   rJ   s     r   Ú
invalidatez_BasePromptCache.invalidate®   s†   € ð ŒZð 	'ð 	'ØŒK�OŠO˜C Ñ&Ô&Ð&ð	'ð 	'ð 	'ñ 	'ô 	'ð 	'ð 	'ð 	'ð 	'ð 	'ð 	'ð 	'øøøð 	'ð 	'ð 	'ð 	'ð 	'ð 	's   ˆ1±5¸5c                óx   — | j         5  | j                             ¦   «          ddd¦  «         dS # 1 swxY w Y   dS )z$Clear all cache entries from memory.N)r7   r6   Úclearr.   s    r   ra   z_BasePromptCache.clear·   s‚   € àŒZð 	 ð 	 ØŒK×ÒÑÔÐð	 ð 	 ð 	 ñ 	 ô 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 øøøð 	 ð 	 ð 	 ð 	 ð 	 ð 	 s   ˆ/¯3¶3úlist[tuple[str, CacheEntry]]c                ó�   ‡ — ‰ j         5  ˆ fd„‰ j                             ¦   «         D ¦   «         cddd¦  «         S # 1 swxY w Y   dS )z.Get list of stale cache entries (thread-safe).c                óR   •— g | ]#\  }}|                      ‰j        ¦  «        ¯||f‘Œ$S r%   )r   r9   )Ú.0rJ   rQ   r   s      €r   ú
<listcomp>z7_BasePromptCache._get_stale_entries.<locals>.<listcomp>¿   sF   ø€ ð ð ð á�C˜Ø—>’> $Ô"3Ñ4Ô4ðØ�e�ðð ð r   N)r7   r6   Úitemsr.   s   `r   Ú_get_stale_entriesz#_BasePromptCache._get_stale_entries¼   s£   ø€ àŒZð 	ð 	ðð ð ð à"&¤+×"3Ò"3Ñ"5Ô"5ðñ ô ð	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	s   ‰%;»?Á?ÚpathúUnion[str, Path]c                óx  — ddl m} t          |¦  «        }|j                             dd¬¦  «         | j        5  i }| j                             ¦   «         D ]v\  }}t          |j	        |j
        ¦  «        rKt          |j	        d¦  «        r|j	                             d¬¦  «        }n!|j	                             ¦   «         }n|j	        }|||<   Œwd|i}d	d	d	¦  «         n# 1 swxY w Y   |                     d
¦  «        }	 t          |d¦  «        5 }	t!          j        ||	d¬¦  «         d	d	d	¦  «         n# 1 swxY w Y   |                     |¦  «         t&                               dt+          |¦  «        › d|› �¦  «         d	S # t,          $ r/}
|                     ¦   «         r|                     ¦   «          |
‚d	}
~
ww xY w)z{Dump cache contents to a JSON file for offline use.

        Args:
            path: Path to the output JSON file.
        r   ©ÚschemasT)ÚparentsÚexist_okÚ
model_dumpÚjson)ÚmodeÚentriesNz.tmpÚwé   )ÚindentzDumped z cache entries to )Ú	langsmithrm   r   ÚparentÚmkdirr7   r6   rg   Ú
isinstancer   ÚPromptCommitÚhasattrrp   ÚdictÚwith_suffixÚopenrq   ÚdumpÚreplacerY   rZ   rU   Ú	ExceptionÚexistsÚunlink)r   ri   Ú
ls_schemasrs   rJ   rQ   Ú
value_dataÚdataÚ	temp_pathÚfÚes              r   r€   z_BasePromptCache.dumpÅ   sW  € ð 	4Ð3Ð3Ð3Ð3Ð3å�D‰zŒzˆØŒ×Ò $°ÐÑ6Ô6Ð6àŒZð 	(ð 	(ØˆGØ"œk×/Ò/Ñ1Ô1ð *ð *‘
��Uå˜eœk¨:Ô+BÑCÔCð -å˜uœ{¨LÑ9Ô9ð 8Ø%*¤[×%;Ò%;ÀÐ%;Ñ%HÔ%H˜
˜
à%*¤[×%5Ò%5Ñ%7Ô%7˜
˜
ð "'¤�Jà)�˜‘�à˜wÐ'ˆDð!	(ð 	(ð 	(ñ 	(ô 	(ð 	(ð 	(ð 	(ð 	(ð 	(ð 	(øøøð 	(ð 	(ð 	(ð 	(ð& ×$Ò$ VÑ,Ô,ˆ	ð		Ý�i Ñ%Ô%ð -¨Ý”	˜$ ¨!Ð,Ñ,Ô,Ð,ð-ð -ð -ñ -ô -ð -ð -ð -ð -ð -ð -øøøð -ð -ð -ð -à×Ò˜dÑ#Ô#Ð#Ý�LŠLÐI¥3 w¡<¤<ÐIÐIÀ4ÐIÐIÑJÔJÐJÐJÐJøÝð 	ð 	ð 	à×ÒÑ!Ô!ð #Ø× Ò Ñ"Ô"Ð"ØˆGøøøøð		øøøsO   ¹BCÃC Ã#C Ã=F  ÄD1Ä%F  Ä1D5Ä5F  Ä8D5Ä9AF  Æ 
F9Æ
*F4Æ4F9c           	     ó\  — ddl m} t          |¦  «        }|                     ¦   «         st                               d|› �¦  «         dS 	 t          |¦  «        5 }t          j        |¦  «        }ddd¦  «         n# 1 swxY w Y   nD# t          j	        t          f$ r+}t                               d|› d|› �¦  «         Y d}~dS d}~ww xY w|                     di ¦  «        }d}t          j        ¦   «         }| j        5  |                     ¦   «         D ]ã\  }	}
t!          | j        ¦  «        | j        k    rt                               d|› �¦  «          n£	 t'          |j        d	¦  «        r|j                             |
¦  «        }n|j                             |
¦  «        }t/          ||¬
¦  «        }|| j        |	<   |dz  }Œ­# t0          $ r*}t                               d|	› d|› �¦  «         Y d}~ŒÜd}~ww xY wddd¦  «         n# 1 swxY w Y   t                               d|› d|› �¦  «         |S )a%  Load cache contents from a JSON file.

        Args:
            path: Path to the JSON file to load.

        Returns:
            Number of entries loaded.

        Loaded entries get a fresh TTL starting from load time.
        If the file doesn't exist or is corrupted, returns 0.
        r   rl   zCache file not found: NzFailed to load cache file ú: rs   z)Reached max cache size, stopping load at Úmodel_validate)r   r   rO   zFailed to load cache entry zLoaded z cache entries from )rw   rm   r   rƒ   rY   rZ   r   rq   ÚloadÚJSONDecodeErrorÚOSErrorÚwarningrR   r   r7   rg   rU   r6   r8   r|   r{   r�   Ú	parse_objr   r‚   )r   ri   r…   r‰   r‡   rŠ   rs   Úloadedr[   rJ   r†   r   rQ   s                r   rŽ   z_BasePromptCache.loadï   sÙ  € ð 	4Ð3Ð3Ð3Ð3Ð3å�D‰zŒzˆà�{Š{‰}Œ}ð 	Ý�LŠLÐ8°$Ð8Ð8Ñ9Ô9Ð9Ø�1ð	Ý�d‘”ð $˜qÝ”y ‘|”|�ð$ð $ð $ñ $ô $ð $ð $ð $ð $ð $ð $øøøð $ð $ð $ð $øøåÔ$¥gÐ.ð 	ð 	ð 	Ý�NŠNÐC¸ÐCÐCÀÐCÐCÑDÔDÐDØ�1�1�1�1�1øøøøð	øøøð —(’(˜9 bÑ)Ô)ˆØˆÝŒi‰kŒkˆàŒZð 	ð 	Ø#*§=¢=¡?¤?ð ð ‘��ZÝ�t”{Ñ#Ô# t¤~Ò5Ð5Ý—L’LÐ!UÈVÐ!UÐ!UÑVÔVÐVØ�Eðå˜zÔ6Ð8HÑIÔIð NØ *Ô 7× FÒ FÀzÑ RÔ R˜˜à *Ô 7× AÒ AÀ*Ñ MÔ M˜õ '¨U¸sÐCÑCÔC�EØ',�D”K Ñ$Ø˜a‘K�F�FøÝ ð ð ð Ý—N’NÐ#KÀÐ#KÐ#KÈÐ#KÐ#KÑLÔLÐLØ�H�H�H�Høøøøðøøøð#	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	õ* 	�ŠÐA˜vÐAÐA¸4ÐAÐAÑBÔBÐBØˆsz   Á
B ÁA:Á.B Á:A>Á>B ÂA>ÂB ÂCÂ CÃCÃ<AHÅA*F>Æ=HÆ>
G2Ç G-Ç(HÇ-G2Ç2HÈHÈHc                ó0   — || _         || _        || _        d S )N)r8   r9   r:   rD   s       r   rC   z_BasePromptCache._configure&  s!   € ð "ˆŒØ'ˆÔØ!9ˆÔÐÐr   N©r<   r(   r   r   r=   r   r   r>   )r   r'   ©r   r>   )rJ   rK   r   rL   r   rM   ©rJ   rK   r   r
   r   rL   r   r>   )rJ   rK   r   r>   )r   rb   )ri   rj   r   r>   )ri   rj   r   r(   )r    r!   r"   r#   Ú	__slots__ÚDEFAULT_PROMPT_CACHE_MAX_SIZEÚ DEFAULT_PROMPT_CACHE_TTL_SECONDSÚ-DEFAULT_PROMPT_CACHE_REFRESH_INTERVAL_SECONDSrE   r3   rG   rI   rR   r]   r_   ra   rh   r€   rŽ   rC   r%   r   r   r5   r5   E   s)  € € € € € ðð ðð ð €Ið 6Ø'GØ*Wð	
ð 
ð 
ð 
ð 
ð. ðð ð ñ „Xðð'ð 'ð 'ð 'ðð ð ð ð>)ð )ð )ð )ð4'ð 'ð 'ð 'ð ð  ð  ð  ð
ð ð ð ð(ð (ð (ð (ðT5ð 5ð 5ð 5ðn:ð :ð :ð :ð :ð :r   r5   c                  óx   ‡ — e Zd ZdZddgZeeedœdˆ fd„Zdd„Z	dd„Z
dd„Zdd„Zdd„Zdd„Zeeedœdd„Zˆ xZS )ÚPromptCacheaí  Thread-safe LRU cache with background thread refresh.

    For use with the synchronous Client.

    Features:
    - In-memory LRU cache with configurable max size
    - Background thread for refreshing stale entries
    - Stale-while-revalidate: returns stale data while refresh happens
    - Thread-safe for concurrent access

    Example:
        >>> def fetch_prompt(key: str) -> PromptCommit:
        ...     return client._fetch_prompt_from_api(key)
        >>> cache = PromptCache(
        ...     max_size=100,
        ...     ttl_seconds=3600,
        ...     fetch_func=fetch_prompt,
        ... )
        >>> cache.set("my-prompt:latest", prompt_commit)
        >>> cached = cache.get("my-prompt:latest")
        >>> cache.shutdown()
    Ú_shutdown_eventÚ_refresh_threadr@   r<   r(   r   r   r=   r   r   r>   c               óŽ   •— t          ¦   «                              |||¬¦  «         t          j        ¦   «         | _        d| _        dS )a�  Initialize the sync prompt cache.

        Args:
            max_size: Maximum entries in cache (LRU eviction when exceeded).
            ttl_seconds: Time before entry is considered stale. Set to None for
                infinite TTL (offline mode - entries never expire).
                Default: 300 (5 minutes).
            refresh_interval_seconds: How often to check for stale entries.
        r@   N)ÚsuperrE   rA   ÚEventrž   rŸ   ©r   r<   r   r=   Ú	__class__s       €r   rE   zPromptCache.__init__K  sO   ø€ õ  	‰Œ×ÒØØ#Ø%=ð 	ñ 	
ô 	
ð 	
õ
  )œÑ0Ô0ˆÔØ;?ˆÔÐÐr   rJ   rK   r   r
   r   rL   c                ój   — | j         €|                      ¦   «          |                      |||¦  «         dS )rT   N)rŸ   Ú_start_refresh_threadr]   ©r   rJ   r   r   s       r   ÚsetzPromptCache.sete  s;   € ð ÔÐ'Ø×&Ò&Ñ(Ô(Ð(Ø�	Š	�#�u˜lÑ+Ô+Ð+Ð+Ð+r   c                ó.   — |                       ¦   «          dS )úgStop background refresh thread.

        Should be called when the client is being cleaned up.
        N)Úshutdownr.   s    r   ÚstopzPromptCache.stopr  s   € ð
 	�Š‰Œˆˆˆr   c                óœ   — | j         �| j                              ¦   «          | j        �$| j                             d¬¦  «         d| _        dS dS )rª   Ng      @)Útimeout)rž   r¨   rŸ   Újoinr.   s    r   r«   zPromptCache.shutdowny  s[   € ð
 ÔÐ+ØÔ ×$Ò$Ñ&Ô&Ð&ØÔÐ+ØÔ ×%Ò%¨cÐ%Ñ2Ô2Ð2Ø#'ˆDÔ Ð Ð ð ,Ð+r   c                óò   — | j         �o| j                             ¦   «          t          j        | j        dd¬¦  «        | _        | j                             ¦   «          t           	                    d¦  «         dS dS )z5Start background thread for refreshing stale entries.NTzPromptCache-refresh)ÚtargetÚdaemonÚnamezStarted cache refresh thread)
r9   rž   ra   rA   ÚThreadÚ_refresh_looprŸ   ÚstartrY   rZ   r.   s    r   r¦   z!PromptCache._start_refresh_thread„  s~   € àÔÐ(ØÔ ×&Ò&Ñ(Ô(Ð(Ý#,Ô#3ØÔ)ØØ*ð$ñ $ô $ˆDÔ ð
 Ô ×&Ò&Ñ(Ô(Ð(Ý�LŠLÐ7Ñ8Ô8Ð8Ð8Ð8ð )Ð(r   c                ó  — | j                              | j        ¦  «        sk	 |                      ¦   «          n4# t          $ r'}t
                               d|› �¦  «         Y d}~nd}~ww xY w| j                              | j        ¦  «        ¯idS dS )z)Background loop to refresh stale entries.z(Unexpected error in cache refresh loop: N)rž   Úwaitr:   Ú_refresh_stale_entriesr‚   rY   Ú	exception©r   rŠ   s     r   rµ   zPromptCache._refresh_loop�  sÀ   € àÔ&×+Ò+¨DÔ,BÑCÔCð 	QðQØ×+Ò+Ñ-Ô-Ð-Ð-øÝð Qð Qð Qå× Ò Ð!OÈAÐ!OÐ!OÑPÔPÐPÐPÐPÐPÐPÐPøøøøðQøøøð Ô&×+Ò+¨DÔ,BÑCÔCð 	Qð 	Qð 	Qð 	Qð 	Qs   ¡6 ¶
A'Á A"Á"A'c                óB  — |                       ¦   «         }|sdS t                               dt          |¦  «        › d�¦  «         |D ]Ø\  }}| j                             ¦   «         r dS |j        �°	 |                     ¦   «         }|                      |||j        ¦  «         | j        xj	        dz  c_	        t                               d|› �¦  «         ŒŒ# t          $ r?}| j        xj        dz  c_        t                               d|› d|› �¦  «         Y d}~ŒÐd}~ww xY wŒÙdS )z)Check for stale entries and refresh them.NzRefreshing ú stale cache entriesrO   zRefreshed cache entry: zFailed to refresh cache entry rŒ   )rh   rY   rZ   rU   rž   Úis_setr   r¨   r;   r+   r‚   r,   r‘   ©r   Ústale_entriesrJ   rQ   Ú	new_valuerŠ   s         r   r¹   z"PromptCache._refresh_stale_entries™  sb  € à×/Ò/Ñ1Ô1ˆàð 	ØˆFå�ŠÐK¥3 }Ñ#5Ô#5ÐKÐKÐKÑLÔLÐLà'ð 	Pð 	P‰JˆC�ØÔ#×*Ò*Ñ,Ô,ð Ø��ØÔ!Ð-ðPØ %× 2Ò 2Ñ 4Ô 4�IØ—H’H˜S )¨UÔ-?Ñ@Ô@Ð@Ø”MÐ+Ô+¨qÑ0Ð+Ô+Ý—L’LÐ!@¸3Ð!@Ð!@ÑAÔAÐAÐAøÝ ð Pð Pð Pà”MÐ0Ô0°AÑ5Ð0Ô0Ý—N’NÐ#NÀCÐ#NÐ#NÈ1Ð#NÐ#NÑOÔOÐOÐOÐOÐOÐOÐOøøøøðPøøøð .ð	Pð 	Ps   Á/A"CÃ
DÃ5DÄDc               ó^   — |                       ¦   «          |                      |||¬¦  «         dS )á  Reconfigure the cache parameters.

        Args:
            max_size: Maximum entries in cache (LRU eviction when exceeded).
            ttl_seconds: Time before entry is considered stale.
            refresh_interval_seconds: How often to check for stale entries.
        r@   N©r¬   rC   rD   s       r   Ú	configurezPromptCache.configure°  s?   € ð 	�	Š	‰ŒˆØ�ŠØØ#Ø%=ð 	ñ 	
ô 	
ð 	
ð 	
ð 	
r   r•   r—   r–   )r    r!   r"   r#   r˜   r™   rš   r›   rE   r¨   r¬   r«   r¦   rµ   r¹   rÅ   Ú__classcell__©r¤   s   @r   r�   r�   1  s  ø€ € € € € ðð ð. #Ð$5Ð6€Ið
 6Ø'GØ*Wð@ð @ð @ð @ð @ð @ð @ð @ð4,ð ,ð ,ð ,ðð ð ð ð	(ð 	(ð 	(ð 	(ð
9ð 
9ð 
9ð 
9ðQð Qð Qð QðPð Pð Pð Pð4 6Ø'GØ*Wð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
r   r�   c                  óv   ‡ — e Zd ZdZdgZeeedœdˆ fd„Zdd„Z	dd„Z
dd„Zdd„Zdd„Zdd„Zeeedœdd„Zˆ xZS )ÚAsyncPromptCachea  Thread-safe LRU cache with asyncio task refresh.

    For use with the asynchronous AsyncClient.

    Features:
    - In-memory LRU cache with configurable max size
    - Asyncio task for refreshing stale entries
    - Stale-while-revalidate: returns stale data while refresh happens
    - Thread-safe for concurrent access

    Example:
        >>> async def fetch_prompt(key: str) -> PromptCommit:
        ...     return await client._afetch_prompt_from_api(key)
        >>> cache = AsyncPromptCache(
        ...     max_size=100,
        ...     ttl_seconds=3600,
        ...     fetch_func=fetch_prompt,
        ... )
        >>> await cache.start()
        >>> cache.set("my-prompt:latest", prompt_commit)
        >>> cached = cache.get("my-prompt:latest")
        >>> await cache.stop()
    Ú_refresh_taskr@   r<   r(   r   r   r=   r   r   r>   c               ó^   •— t          ¦   «                              |||¬¦  «         d| _        dS )ag  Initialize the async prompt cache.

        Args:
            max_size: Maximum entries in cache (LRU eviction when exceeded).
            ttl_seconds: Time before entry is considered stale. Set to None for
                infinite TTL (offline mode - entries never expire).
            refresh_interval_seconds: How often to check for stale entries.
        r@   N)r¡   rE   rÊ   r£   s       €r   rE   zAsyncPromptCache.__init__á  s@   ø€ õ 	‰Œ×ÒØØ#Ø%=ð 	ñ 	
ô 	
ð 	
ð
 <@ˆÔÐÐr   rJ   rK   r   r
   r   úCallable[[], Awaitable[Any]]c              ƒ  óz   K  — | j         €|                      ¦   «         ƒ d{V —† |                      |||¦  «         dS )zÝSet a value in the cache.

        Args:
            key: The cache key (prompt identifier).
            value: The value to cache.
            refresh_func: Async function to refresh this cache entry when stale.
        N)rÊ   r¶   r]   r§   s       r   ÚasetzAsyncPromptCache.aset÷  sM   è è € ð ÔÐ%Ø—*’*‘,”,ÐÐÐÐÐÐÐØ�	Š	�#�u˜lÑ+Ô+Ð+Ð+Ð+r   c              ƒ  ó¼   K  — | j         €dS | j        �dS t          j        |                      ¦   «         d¬¦  «        | _        t
                               d¦  «         dS )züStart async background refresh loop.

        Must be called from an async context. Creates an asyncio task that
        periodically checks for stale entries and refreshes them.
        Does nothing if ttl_seconds is None (infinite TTL mode).
        NzAsyncPromptCache-refresh)r³   z Started async cache refresh task)r9   rÊ   ÚasyncioÚcreate_taskrµ   rY   rZ   r.   s    r   r¶   zAsyncPromptCache.start  sk   è è € ð ÔÐ$ØˆFàÔÐ)àˆFå$Ô0Ø×ÒÑ Ô Ø+ð
ñ 
ô 
ˆÔõ 	�ŠÐ7Ñ8Ô8Ð8Ð8Ð8r   c                óX   — | j         �"| j                              ¦   «          d| _         dS dS )z£Stop background refresh task.

        Synchronous wrapper that cancels the refresh task.
        For proper cleanup in async context, use stop() instead.
        N)rÊ   Úcancelr.   s    r   r«   zAsyncPromptCache.shutdown  s8   € ð ÔÐ)ØÔ×%Ò%Ñ'Ô'Ð'Ø!%ˆDÔÐÐð *Ð)r   c              ƒ  óØ   K  — | j         €dS | j                              ¦   «          	 | j         ƒ d{V —† n# t          j        $ r Y nw xY wd| _         t                               d¦  «         dS )zlStop async background refresh loop.

        Cancels the refresh task and waits for it to complete.
        Nz Stopped async cache refresh task)rÊ   rÓ   rÐ   ÚCancelledErrorrY   rZ   r.   s    r   r¬   zAsyncPromptCache.stop$  s’   è è € ð
 ÔÐ%ØˆFàÔ×!Ò!Ñ#Ô#Ð#ð	ØÔ$Ð$Ð$Ð$Ð$Ð$Ð$Ð$Ð$øÝÔ%ð 	ð 	ð 	ØˆDð	øøøà!ˆÔÝ�ŠÐ7Ñ8Ô8Ð8Ð8Ð8s   ¦4 ´AÁAc              ƒ  ó  K  — 	 	 t          j        | j        ¦  «        ƒ d{V —† |                      ¦   «         ƒ d{V —† nC# t           j        $ r ‚ t
          $ r'}t                               d|› �¦  «         Y d}~nd}~ww xY wŒ)z/Async background loop to refresh stale entries.TNz.Unexpected error in async cache refresh loop: )rÐ   Úsleepr:   r¹   rÕ   r‚   rY   rº   r»   s     r   rµ   zAsyncPromptCache._refresh_loop4  sÌ   è è € ð	WðWÝ”m DÔ$:Ñ;Ô;Ð;Ð;Ð;Ð;Ð;Ð;Ð;Ø×1Ò1Ñ3Ô3Ð3Ð3Ð3Ð3Ð3Ð3Ð3Ð3øÝÔ)ð ð ð ØÝð Wð Wð Wå× Ò Ð!UÐRSÐ!UÐ!UÑVÔVÐVÐVÐVÐVÐVÐVøøøøðWøøøð	Ws   …9? ¿A?ÁA:Á:A?c              ƒ  ó&  K  — |                       ¦   «         }|sdS t                               dt          |¦  «        › d�¦  «         |D ]È\  }}|j        �¼	 |                     ¦   «         ƒ d{V —†}|                      |||j        ¦  «        ƒ d{V —† | j        xj        dz  c_        t                               d|› �¦  «         Œ|# t          $ r?}| j        xj	        dz  c_	        t           
                    d|› d|› �¦  «         Y d}~ŒÀd}~ww xY wŒÉdS )z8Check for stale entries and refresh them asynchronously.NzAsync refreshing r½   rO   zAsync refreshed cache entry: z$Failed to async refresh cache entry rŒ   )rh   rY   rZ   rU   r   rÎ   r;   r+   r‚   r,   r‘   r¿   s         r   r¹   z'AsyncPromptCache._refresh_stale_entries@  sm  è è € à×/Ò/Ñ1Ô1ˆàð 	ØˆFå�ŠÐQ­¨]Ñ);Ô);ÐQÐQÐQÑRÔRÐRà'ð 
	Vð 
	V‰JˆC�ØÔ!Ð-ðVØ&+×&8Ò&8Ñ&:Ô&:Ð :Ð :Ð :Ð :Ð :Ð :�IØŸ)š) C¨°EÔ4FÑGÔGÐGÐGÐGÐGÐGÐGÐGØ”MÐ+Ô+¨qÑ0Ð+Ô+Ý—L’LÐ!FÀÐ!FÐ!FÑGÔGÐGÐGøÝ ð Vð Vð Và”MÐ0Ô0°AÑ5Ð0Ô0Ý—N’NÐ#TÈ#Ð#TÐ#TÐQRÐ#TÐ#TÑUÔUÐUÐUÐUÐUÐUÐUøøøøðVøøøð .ð
	Vð 
	Vs   ÁA.CÃ
DÃ5DÄDc             ƒ  ól   K  — |                       ¦   «         ƒ d{V —† |                      |||¦  «         dS )rÃ   NrÄ   rD   s       r   rÅ   zAsyncPromptCache.configureU  sE   è è € ð �iŠi‰kŒkÐÐÐÐÐÐÐØ�Š˜ +Ð/GÑHÔHÐHÐHÐHr   r•   )rJ   rK   r   r
   r   rÌ   r   r>   r–   )r    r!   r"   r#   r˜   r™   rš   r›   rE   rÎ   r¶   r«   r¬   rµ   r¹   rÅ   rÆ   rÇ   s   @r   rÉ   rÉ   Æ  s!  ø€ € € € € ðð ð0 !Ð!€Ið
 6Ø'GØ*Wð@ð @ð @ð @ð @ð @ð @ð @ð,,ð ,ð ,ð ,ð9ð 9ð 9ð 9ð(&ð &ð &ð &ð9ð 9ð 9ð 9ð 
Wð 
Wð 
Wð 
WðVð Vð Vð Vð0 6Ø'GØ*WðIð Ið Ið Ið Ið Ið Ið Ið Ið Ir   rÉ   r@   r<   r(   r   r   r=   r   r   r>   c                ó@   — t                                | ||¬¦  «         dS ©aâ  Configure the global prompt cache.

    This should be called before any cache instances are created or used.

    Args:
        max_size: Maximum entries in cache (LRU eviction when exceeded).
        ttl_seconds: Time before entry is considered stale.
        refresh_interval_seconds: How often to check for stale entries.

    Example:
        >>> from langsmith import configure_global_prompt_cache
        >>> configure_global_prompt_cache(max_size=200, ttl_seconds=7200)
    r@   N)Úprompt_cache_singletonrÅ   r@   s      r   Úconfigure_global_prompt_cacherÝ   l  s4   € õ& ×$Ò$ØØØ!9ð %ñ ô ð ð ð r   c              ƒ  óP   K  — t                                | ||¬¦  «        ƒ d{V —† dS rÛ   )Úasync_prompt_cache_singletonrÅ   r@   s      r   Ú#configure_global_async_prompt_cacherà   †  sV   è è € õ& '×
0Ò
0ØØØ!9ð 1ñ ô ð ð ð ð ð ð ð ð ð r   c                 ó>   — t          j        dt          d¬¦  «         d S )NzcThe 'Cache' class is deprecated and will be removed in a future version. Use 'PromptCache' instead.é   )Ú
stacklevel)ÚwarningsÚwarnÚDeprecationWarningr%   r   r   Ú_deprecated_cache_class_warningrç   £  s0   € Ý„Mð	%åØð	ñ ô ð ð ð r   c                  ó.   ‡ — e Zd ZdZeeedœdˆ fd„Zˆ xZS )ÚCachez:Deprecated alias for PromptCache. Use PromptCache instead.r@   r<   r(   r   r   r=   r   r   r>   c               ól   •— t          ¦   «          t          ¦   «                              |||¬¦  «         dS )a  Initialize the deprecated Cache class.

        Args:
            max_size: Maximum entries in cache (LRU eviction when exceeded).
            ttl_seconds: Time before entry is considered stale.
            refresh_interval_seconds: How often to check for stale entries.
        r@   N©rç   r¡   rE   r£   s       €r   rE   zCache.__init__¯  óE   ø€ õ 	(Ñ)Ô)Ð)Ý‰Œ×ÒØØ#Ø%=ð 	ñ 	
ô 	
ð 	
ð 	
ð 	
r   r•   ©	r    r!   r"   r#   r™   rš   r›   rE   rÆ   rÇ   s   @r   ré   ré   ¬  sX   ø€ € € € € ØDÐDð
 6Ø'GØ*Wð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
r   ré   c                  ó.   ‡ — e Zd ZdZeeedœdˆ fd„Zˆ xZS )Ú
AsyncCachezDDeprecated alias for AsyncPromptCache. Use AsyncPromptCache instead.r@   r<   r(   r   r   r=   r   r   r>   c               ól   •— t          ¦   «          t          ¦   «                              |||¬¦  «         dS )a  Initialize the deprecated AsyncCache class.

        Args:
            max_size: Maximum entries in cache (LRU eviction when exceeded).
            ttl_seconds: Time before entry is considered stale.
            refresh_interval_seconds: How often to check for stale entries.
        r@   Nrë   r£   s       €r   rE   zAsyncCache.__init__È  rì   r   r•   rí   rÇ   s   @r   rï   rï   Å  sX   ø€ € € € € ØNÐNð
 6Ø'GØ*Wð
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
r   rï   r•   r–   )*r#   Ú
__future__r   rÐ   rq   ÚloggingrA   r   rä   Úabcr   Úcollectionsr   Úcollections.abcr   Údataclassesr   Úpathlibr   Útypingr	   r
   r   r   r   Ú	getLoggerrY   rš   r™   r›   r   r'   r5   r�   rÉ   rÜ   rß   rÝ   rà   rç   ré   rï   r%   r   r   ú<module>rú      sÿ  ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø €€€Ø Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø #Ð #Ð #Ð #Ð #Ð #Ø %Ð %Ð %Ð %Ð %Ð %Ø !Ð !Ð !Ð !Ð !Ð !Ø Ð Ð Ð Ð Ð Ø @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @àð 	Øà	ˆÔ	Ð,Ñ	-Ô	-€ð $*Ð  Ø #Ð Ø02Ð -ð ð=ð =ð =ð =ð =ñ =ô =ñ „ð=ð ð7ð 7ð 7ð 7ð 7ñ 7ô 7ñ „ð7ð(i:ð i:ð i:ð i:ð i:�sñ i:ô i:ð i:ðXR
ð R
ð R
ð R
ð R
Ð"ñ R
ô R
ð R
ðj^Ið ^Ið ^Ið ^Ið ^IÐ'ñ ^Iô ^Ið ^IðD %˜™œÐ Ø/Ð/Ñ1Ô1Ð ð
 2Ø#CØ&Sð	ð ð ð ð ð ð8 2Ø#CØ&Sð	ð ð ð ð ð ð:ð ð ð ð
ð 
ð 
ð 
ð 
ˆKñ 
ô 
ð 
ð2
ð 
ð 
ð 
ð 
Ð!ñ 
ô 
ð 
ð 
ð 
r   