Ë
    uPêjÉ ã            	       óz  — U d 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Zddlm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZmZmZmZmZ ddlZddlmZmZ ddlmZmZmZmZ dd	lm Z  dd
l!m"Z" ddl#m$Z$m%Z%m&Z& ddl'm(Z( ddl)m*Z* er%ddl+m,Z- ddl.m/Z/m0Z0 ddl1m2Z2 ddl3m4Z4 e2Z5e4Z6e/Z7e0Z8e-Z,n
eZ5eZ6eZ7eZ8eZ,d+de9de:fd„Z; G d„ d«      Z< ed«      Z= edd¬«      Z>eee9      e?d<   de@de:fd„ZA ej„                  d¬«      deCeDdf   fd „«       ZEd!eFdeGfd"„ZHd#e<d!eFddfd$„ZId#e<d%e:d&e
g e	e=   f   de=fd'„ZJd(„ ZK G d)„ d*e*«      ZLy),z€
Redis Cache implementation

Has 4 primary methods:
    - set_cache
    - get_cache
    - async_set_cache
    - async_get_cache
é    N)Ú	AwaitableÚCallableÚSequence)Ú
ContextVar)Ú	timedelta)ÚTYPE_CHECKINGÚAnyÚFinalÚTypeVarÚcast)Úprint_verboseÚverbose_logger)ÚDEFAULT_REDIS_MAJOR_VERSIONÚREDIS_CIRCUIT_BREAKER_ENABLEDÚ'REDIS_CIRCUIT_BREAKER_FAILURE_THRESHOLDÚ&REDIS_CIRCUIT_BREAKER_RECOVERY_TIMEOUT)Ú!_get_parent_otel_span_from_kwargs)Úcoroutine_checker)ÚRedisPipelineIncrementOperationÚRedisPipelineLpopOperationÚRedisPipelineRpushOperation)ÚServiceTypesé   )Ú	BaseCache)ÚSpan)ÚRedisÚRedisCluster)ÚPipeline)ÚClusterPipelineÚ
num_framesÚreturnc                 óF  — 	 t        j                  «       }|€y|j                  }|€y|j                  }|€yg }t        | «      D ]9  }|€ n5|j                  j
                  }|j                  |«       |j                  }Œ; |sydj                  |«      S # t        $ r Y yw xY w)a  
    Get the function names from the previous 1-2 functions in the call stack.

    Args:
        num_frames: Number of previous frames to include (default: 2)

    Returns:
        A string with format "current_function <- caller_function [<- grandparent_function]"
    Úunknownz <- )	ÚinspectÚcurrentframeÚf_backÚrangeÚf_codeÚco_nameÚappendÚjoinÚ	Exception)r    Úcurrent_framer&   ÚframeÚfunction_namesÚ_Ú	func_names          ú`/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/caching/redis_cache.pyÚ_get_call_stack_infor3   =   s´   € ðÜ&×3Ñ3Ó5ˆØÐ Øð &×,Ñ,ˆØˆ>ØØ—‘ˆØˆ=ØØ "ˆä�zÓ"ò 	!ˆAØˆ}ÙØŸ™×,Ñ,ˆIØ×!Ñ! )Ô,Ø—L‘L‰Eð	!ñ Øà�{‰{˜>Ó*Ð*øÜò Ùðús'   ‚B ™B ¨B ·AB ÂB Â	B ÂB c            	       óT   — e Zd ZdZdZdZdZ	 ddedededd	fd
„Z	defd„Z
dd„Zdd„Zy	)ÚRedisCircuitBreakeraç  
    Tracks Redis health for a RedisCache instance.

    States:
      CLOSED    - normal, Redis is called
      OPEN      - Redis is down, raise immediately (no network call)
      HALF_OPEN - recovery probe: allow one request through

    Transitions:
      CLOSED    -> OPEN      after failure_threshold consecutive failures
      OPEN      -> HALF_OPEN after recovery_timeout seconds
      HALF_OPEN -> CLOSED    on success
      HALF_OPEN -> OPEN      on failure (resets timer)
    ÚclosedÚopenÚ	half_openÚfailure_thresholdÚrecovery_timeoutÚenabledr!   Nc                 ól   — || _         || _        || _        d| _        d | _        | j
                  | _        y )Nr   )r9   r:   r;   Ú_failure_countÚ
_opened_atÚCLOSEDÚ_state)Úselfr9   r:   r;   s       r2   Ú__init__zRedisCircuitBreaker.__init__x   s5   € ð "3ˆÔØ 0ˆÔØˆŒØˆÔØ(,ˆŒØ—k‘kˆ�ó    c                 ó  — | j                   sy| j                  | j                  k(  ry| j                  | j                  k(  rEt	        j                  «       | j
                  xs dz
  | j                  kD  r| j                  | _        yyy)z.Returns True if Redis calls should be skipped.FTr   )r;   r@   Ú	HALF_OPENÚOPENÚtimer>   r:   ©rA   s    r2   Úis_openzRedisCircuitBreaker.is_open…   sg   € à�|Š|ØØ�;‰;˜$Ÿ.™.Ò(ð Ø�;‰;˜$Ÿ)™)Ò#Ü�y‰y‹{˜dŸo™oÒ2°Ñ3°d×6KÑ6KÒKØ"Ÿn™n�”ØØØrC   c                 óX  — | j                   sy | xj                  dz  c_        t        j                  «       | _        | j                  | j                  k\  rV| j
                  | j                  k7  r+t        j                  d| j                  | j                  «       | j                  | _        y y )Nr   u_   Redis circuit breaker OPENED after %d consecutive failures â€” fast-failing Redis calls for %ds)
r;   r=   rG   r>   r9   r@   rF   r   Úwarningr:   rH   s    r2   Úrecord_failurez"RedisCircuitBreaker.record_failure•   sƒ   € Ø�|Š|ØØ×Ò˜qÑ ÕÜŸ)™)›+ˆŒØ×Ñ $×"8Ñ"8Ò8Ø�{‰{˜dŸi™iÒ'Ü×&Ñ&ØuØ×'Ñ'Ø×)Ñ)ôð
 Ÿ)™)ˆD�Kð 9rC   c                 óª   — | j                   sy | j                  | j                  k(  rt        j                  d«       d| _        | j                  | _        y )Nu0   Redis circuit breaker CLOSED â€” Redis recoveredr   )r;   r@   rE   r   Úinfor=   r?   rH   s    r2   Úrecord_successz"RedisCircuitBreaker.record_success£   s>   € Ø�|Š|ØØ�;‰;˜$Ÿ.™.Ò(Ü×ÑÐ RÔSØˆÔØ—k‘kˆ�rC   )T)r!   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r?   rF   rE   ÚintÚboolrB   rI   rL   rO   © rC   r2   r5   r5   d   s^   „ ñð €FØ€DØ€Ið ñ	"àð"ð ð"ð ð	"ð
 
ó"ð˜ó ó $ô"rC   r5   Ú_RedisCallResultÚ litellm_swallowed_redis_failures)ÚdefaultÚ_swallowed_redis_failuresÚvaluec                 óH   — t        | «      j                  › dt        | «      › �S )Nú-)ÚtyperP   Úid)r[   s    r2   Ú_opaque_kwarg_keyr`   ²   s"   € Ü�5‹k×"Ñ"Ð# 1¤R¨£Y KÐ0Ð0rC   )Úmaxsize.c                  ó^   — ddl m} m} ddl m} ddl m} ||| |t
        t        j                  fS )a  Exception types that mean the Redis backend itself is unhealthy.

    Command and data errors say nothing about connectivity: an INCR against a non-numeric
    value or an undecodable cached entry is a request problem, and counting those would let
    a caller trip the shared breaker on demand, dropping rate limiting to per-process
    counters that spreading traffic across replicas can outrun.

    Imported lazily because this module is reachable from a base ``import litellm`` while
    redis is not a base dependency.
    r   )ÚBusyLoadingErrorÚClusterDownError)ÚConnectionError)ÚTimeoutError)Úredis.exceptionsrc   rd   re   rf   ÚOSErrorÚasyncio)rc   rd   ÚRedisConnectionErrorÚRedisTimeoutErrors       r2   Ú_redis_health_error_typesrl   ¶   s,   € ÷ DÝHÝBà Ð"3Ð5EÐGWÔY`Ôbi×bvÑbvÐwÐwrC   Úexcc                 óJ   — 	 t        | t        «       «      S # t        $ r Y yw xY w)zSTrue when ``exc`` indicates Redis is unreachable rather than the request being bad.T)Ú
isinstancerl   ÚImportError)rm   s    r2   Ú_is_redis_health_failurerq   É   s*   € ðÜ˜#Ô8Ó:Ó;Ð;øÜò Ùðús   ‚ –	"¡"Úbreakerc                 ó�   — t        |«      sy| j                  «        t        j                  t        j	                  «       dz   «       y)aõ  Record a Redis failure that the calling method is about to swallow.

    The marker is a ContextVar rather than a counter on the breaker because breakers are
    shared by every concurrent caller. A plain shared counter cannot tell "my call failed"
    from "some other in-flight call failed", so a success overlapping someone else's
    failure would be discarded and a Redis that is answering would still be evicted.
    asyncio gives each task its own copy of the context, so this is per-call.
    Nr   )rq   rL   rZ   ÚsetÚget)rr   rm   s     r2   Ú_record_swallowed_redis_failurerv   Ñ   s8   € ô $ CÔ(ØØ×ÑÔÜ×!Ñ!Ô";×"?Ñ"?Ó"AÀAÑ"EÕFrC   ÚnameÚcallc              ƒ   ó>  K  — | j                  «       rt        d|› �«      ‚t        j                  «       }	  |«       ƒ d{  –—† }t        j                  «       |k(  r| j                  «        |S 7 Œ-# t        $ r!}t	        |«      r| j                  «        ‚ d}~ww xY w­w)a9  Run one Redis coroutine under a circuit breaker.

    Shared by the method decorator and the Lua script executor so both feed the same
    health signal. Success is recorded only when nothing failed while ``call`` ran,
    because several Redis methods catch their own connection errors and return a default.
    u+   Redis circuit breaker is open â€” skipping N)rI   r,   rZ   ru   rq   rL   rO   )rr   rw   rx   Úswallowed_beforeÚresultÚes         r2   Ú_run_under_circuit_breakerr}   à   s’   è ø€ ð ‡�ÔÜÐEÀdÀVÐLÓMÐMÜ7×;Ñ;Ó=ÐðÙ"›fŸˆô
 !×$Ñ$Ó&Ð*:Ò:Ø×ÑÔ Ø€Mð %ùÜò Ü# AÔ&Ø×"Ñ"Ô$Øûðüs:   ‚3B¶
A0 Á A.ÁA0 Á)BÁ.A0 Á0	BÁ9BÂBÂBc                 óB   ‡ — t        j                  ‰ «      ˆ fd„«       }|S )ay  
    Decorator for RedisCache async methods.
    Checks the circuit breaker before each call; records success/failure after.
    Does not apply to ping/disconnect/test_connection (health/teardown must always run).

    A returning method is not proof of a healthy Redis: several methods catch their own
    connection errors and return a default so callers degrade rather than fail. Counting
    those as successes reset the failure streak on every request, so the breaker could
    never open and Redis was never taken out of the pool. Success is therefore recorded
    only when no failure was registered while the method ran.
    c              Ÿ   ót   •‡ ‡‡K  — t        ‰ j                  ‰j                  ˆˆˆˆ fd„«      ƒ d {  –—† S 7 Œ­w)Nc                  ó   •—  ‰‰g‰ ¢­i ‰¤ŽS ©NrV   )ÚargsÚkwargsÚmethodrA   s   €€€€r2   ú<lambda>z?_redis_circuit_breaker_guard.<locals>.wrapper.<locals>.<lambda>	  s   ø€ ¹FÀ4Ð<YÈ$Ò<YÐRXÑ<Y€ rC   )r}   Ú_circuit_breakerrP   )rA   r‚   rƒ   r„   s   ```€r2   Úwrapperz-_redis_circuit_breaker_guard.<locals>.wrapper  s0   ûè ø€ ä/Ø×!Ñ! 6§?¡?Ö4Yó
÷ 
ð 	
ð 
ús   †+8±6²8)Ú	functoolsÚwraps)r„   r‡   s   ` r2   Ú_redis_circuit_breaker_guardrŠ   ù   s'   ø€ ô ‡_�_�VÓó
ó ð
ð
 €NrC   c                   óž  ‡ — e Zd Z	 	 	 	 	 	 	 dMdedz  dedz  dedz  dedz  fˆ fd„Zd„ Zde	fd	„Z
de	fd
„Zdefd„Zdeez  fd„Zdedefd„Zdefd„Zd„ ZdNdededz  defd„ZedOdededefd„«       Zdededee   f   fd„Zdededee   f   fd„Zed„ «       Zdeez  deeee f      dedz  defd„Z!e	 dNdeeee f      dedz  fd „«       Z"d!ededededz  ddf
d"„Z#edededz  fd#„«       Z$ed$„ «       Z%e	 	 	 dPdededz  d%e&dz  d&e'def
d'„«       Z(e	 dNdedededz  dedz  fd(„«       Z)d)„ Z*d*efd+„Z+dNd%e&dz  fd,„Z,d-ee   dee-ez  dz     fd.„Z.d-ee   dee-ez  dz     fd/„Z/	 dNd0ee   eedz     z  d%e&dz  de0fd1„Z1edNd%e&dz  fd2„«       Z2e	 dNd0ee   eedz     z  d%e&dz  de0fd3„«       Z3de'fd4„Z4de'fd5„Z5ed6„ «       Z6defd7„Z7d8„ Z8d9„ Z9d:„ Z:d;„ Z;de0fd<„Z<edefd=„«       Z=d>„ Z>ded?ee?   dee   dz  fd@„Z@ed?ee?   dee   dz  fdA„«       ZAedededz  fdB„«       ZBe	 dNdedCeee-z  ez  ez     d%e&dz  defdD„«       ZCdedEeeD   dee   fdF„ZEedEeeD   dee   fdG„«       ZFdedededee-   fdH„ZGe	 	 dQdededz  d%e&dz  deee   z  fdI„«       ZHdedJeeI   deee   dz     fdK„ZJedJeeI   deee   dz     fdL„«       ZKˆ xZLS )RÚ
RedisCacheNÚredis_flush_sizeÚ	namespaceÚstartup_nodesÚsocket_timeoutc                 ó>  •— ddl m}	 ddlm}
m} i }|�||d<   |�||d<   |�||d<   |�||d<   |�||d	<   |j                  d
d «      �&t        |d
   |	«      r|j                  d
«      | _        n |	«       | _        |j                  |«        |
di |¤Ž| _
        d | _        || _         |di |¤Ž| _        || _        g | _        |€d| _        n|| _        d| _        	 t%        j&                  | j                  «      s"| j                  j)                  «       d   | _        t-        t.        t0        t2        ¬«      | _        | j7                  «        t8        j:                  �(t<        ‰| �}  tA        t8        j:                  «      ¬«       y t<        ‰| �}  «        y # t*        $ r Y Œ�w xY w)Nr   )ÚServiceLoggingé   )Úget_redis_clientÚget_redis_connection_poolÚhostÚportÚpasswordr�   r�   Úservice_logger_objéd   ÚUnknownÚredis_version)r9   r:   r;   )Údefault_ttlrV   )!Úlitellm._service_loggerr’   Ú_redisr”   r•   ru   ro   Úpopr™   ÚupdateÚredis_clientÚredis_async_clientÚredis_kwargsÚasync_redis_conn_poolrŽ   Úredis_batch_writing_bufferr�   rœ   r   Úis_async_callablerN   r,   r5   r   r   r   r†   Ú_setup_health_pingsÚlitellmÚdefault_redis_ttlÚsuperrB   rT   )rA   r–   r—   r˜   r�   rŽ   r�   r�   rƒ   r’   r”   r•   r¤   Ú	__class__s                €r2   rB   zRedisCache.__init__  sµ  ø€ õ 	;çHà ˆØÐØ#'ˆL˜Ñ ØÐØ#'ˆL˜Ñ ØÐØ'/ˆL˜Ñ$ØÐ$Ø,9ˆL˜Ñ)ØÐ%Ø-;ˆLÐ)Ñ*ð �:‰:Ð*¨DÓ1Ð=Ä*ØÐ'Ñ(¨.ôC
ð '-§j¡jÐ1EÓ&FˆDÕ#á&4Ó&6ˆDÔ#à×Ñ˜FÔ#Ù,Ñ<¨|Ñ<ˆÔØZ^ˆÔØ(ˆÔÙ%>Ñ%NÀÑ%NˆÔ"ð #ˆŒà02ˆÔ'ØÐ#Ø),ˆDÕ!à$4ˆDÔ!Ø&ˆÔð	Ü$×6Ñ6°t×7HÑ7HÔIØ%)×%6Ñ%6×%;Ñ%;Ó%=¸oÑ%N�Ô"ô !4ÜEÜCÜ1ô!
ˆÔð 	× Ñ Ô"ä×$Ñ$Ð0Ü‰GÑ¬¬W×-FÑ-FÓ)GÐÕHä‰GÑÕøô ò 	Ùð	ús   ÃAF Æ	FÆFc           	      ó8  — 	 t        j                  «       j                  | j                  «       «      }	 t        | j                  d«      r| j                  j                  «        yy# t        $ ra}dt        |«      v rt        j                  d«       n4t        j                  d|dt        |«      i¬«       | j                  |«       Y d}~Œ˜d}~ww xY w# t        $ r=}t        j                  ddt        |«      i¬«       | j                  |«       Y d}~yd}~ww xY w)	z,Setup async and sync health pings for Redis.zno running event loopz1Ignoring async redis ping. No running event loop.z+Error connecting to Async Redis client - %sÚerror)ÚextraNÚpingz%Error connecting to Sync Redis client)ri   Úget_running_loopÚcreate_taskr°   r,   Ústrr   Údebugr®   Ú_handle_async_ping_errorÚhasattrr¢   Ú_handle_sync_ping_error)rA   r0   r|   s      r2   r¨   zRedisCache._setup_health_pingsW  sð   € ð	1Ü×(Ñ(Ó*×6Ñ6°t·y±y³{ÓCˆAð	,Ü�t×(Ñ(¨&Ô1Ø×!Ñ!×&Ñ&Õ(ð 2øô ò 		1Ø&¬#¨a«&Ñ0Ü×$Ñ$Ð%XÕYä×$Ñ$ØAØØ"¤C¨£FÐ+õð
 ×-Ñ-¨aÔ0ÿøð		1ûô ò 	,Ü× Ñ Ð!HÐQXÔZ]Ð^_ÓZ`ÐPaÕbØ×(Ñ(¨×+Ñ+ûð	,ús/   ‚1A& ´0C Á&	CÁ/ACÃCÃ	DÃ3DÄDr|   c                 óö   — 	 t        j                  «       }t        j                  «       }|}|j                  | j                  j                  t        j                  ||z
  |d¬«      «       y# t        $ r Y yw xY w)z2Handle async ping error with service failure hook.Úredis_async_ping©ÚserviceÚdurationr®   Ú	call_typeN©	ri   r±   rG   r²   r™   Úasync_service_failure_hookr   ÚREDISr,   ©rA   r|   ÚloopÚ
start_timeÚend_times        r2   rµ   z#RedisCache._handle_async_ping_erroro  sx   € ð	Ü!×2Ñ2Ó4ˆDÜ $§	¡	£ˆJØ(ˆHØ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø%¨
Ñ2ØØ0ð	 Có õøô ò 	Ùð	úó   ‚A)A, Á,	A8Á7A8c                 óö   — 	 t        j                  «       }t        j                  «       }|}|j                  | j                  j                  t        j                  ||z
  |d¬«      «       y# t        $ r Y yw xY w)z1Handle sync ping error with service failure hook.Úredis_sync_pingrº   Nr¾   rÁ   s        r2   r·   z"RedisCache._handle_sync_ping_error€  sx   € ð	Ü!×2Ñ2Ó4ˆDÜ $§	¡	£ˆJØ(ˆHØ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø%¨
Ñ2ØØ/ð	 Có õøô ò 	Ùð	úrÅ   r!   c                 óò   — t        | j                  j                  «       «      }t        j                  |dt
        ¬«      }t        j                  |j                  «       «      j                  «       dd }d|› �S )z³
        Generate a cache key for the async Redis client based on connection parameters.
        This ensures different Redis configurations use different cached clients.
        T)Ú	sort_keysrY   Né   zasync-redis-client-)
Úsortedr¤   ÚitemsÚjsonÚdumpsr`   ÚhashlibÚsha256ÚencodeÚ	hexdigest)rA   Úsorted_kwargsÚ
kwargs_strÚkwargs_hashs       r2   Ú_get_async_client_cache_keyz&RedisCache._get_async_client_cache_key‘  sd   € ô  & d×&7Ñ&7×&=Ñ&=Ó&?Ó@ˆÜ ŸJ™J }ÀÔN_Ô`ˆ
Ü$Ÿ^™^¨J×,=Ñ,=Ó,?Ó@×JÑJÓLÈSÈbÐQˆØ$ [ MÐ2Ð2rC   c                 ó8  — ddl m} ddlm}m} | j                  «       }|j                  |¬«      }|�t        t        t        z  |«      }nH |di | j                  ¤Ž| _         |dd| j                  i| j                  ¤Ž}|j                  ||¬«       || _        |S )	Nr   )Úin_memory_llm_clients_cacher“   )Úget_redis_async_clientr•   ©ÚkeyÚconnection_pool©rÛ   r[   rV   )r©   rØ   rŸ   rÙ   r•   rÖ   Ú	get_cacher   Úasync_redis_clientÚasync_redis_cluster_clientr¤   r¥   Ú	set_cacher£   )rA   rØ   rÙ   r•   Ú	cache_keyÚcached_clientr£   s          r2   Úinit_async_clientzRedisCache.init_async_clientœ  s¡   € õ 	8çNà×;Ñ;Ó=ˆ	Ø:×DÑDÈÐDÓSˆØÐ$Ü!%Ô&8Ô;UÑ&UÐWdÓ!eÑñ *CÑ)WÀT×EVÑEVÑ)WˆDÔ&Ù!7Ñ!xÈ×HbÑHbÐ!xÐfj×fwÑfwÑ!xÐØ'×1Ñ1°iÐGYÐ1ÔZà"4ˆÔØ!Ð!rC   rÛ   c                 ó†   — |€|S | j                   r0|j                  | j                   dz   «      s| j                   dz   |z   }|S )zD
        Make sure each key starts with the given namespace
        ú:)rŽ   Ú
startswith©rA   rÛ   s     r2   Úcheck_and_fix_namespacez"RedisCache.check_and_fix_namespace°  sA   € ð ˆ;ØˆJØ�>Š> #§.¡.°·±À#Ñ1EÔ"FØ—.‘. 3Ñ&¨Ñ,ˆCàˆ
rC   c                 ó  — | j                   dk(  rt        S 	 t        | j                   «      j                  «       }d|v rt	        |j                  d«      d   «      }|S t	        t        |«      «      }|S # t        t        f$ r	 t        cY S w xY w)aÉ  
        Parse Redis version to extract the major version number.

        Handles multiple version formats:
        - Strings: "7.0.0", "6", "7.0.0-rc1", " 7.0.0 "
        - Floats: 7.0 (e.g., from AWS ElastiCache Valkey)
        - Integers: 7
        - Malformed: "latest", "", "Unknown" (defaults to DEFAULT_REDIS_MAJOR_VERSION)

        Returns:
            int: The major version number (defaults to DEFAULT_REDIS_MAJOR_VERSION if unparseable)
        r›   ú.r   )	rœ   r   r³   ÚstriprT   ÚsplitÚfloatÚ
ValueErrorÚAttributeError)rA   Úversion_strÚmajor_versions      r2   Ú_parse_redis_major_versionz%RedisCache._parse_redis_major_version»  s‘   € ð ×Ñ Ò*Ü.Ð.ð	/Ü!$ T×%7Ñ%7Ó!8×!>Ñ!>Ó!@ˆKà�kÑ!Ü # K×$5Ñ$5°cÓ$:¸1Ñ$=Ó >�ð !Ð ô !$¤E¨+Ó$6Ó 7�Ø Ð øÜœNÐ+ò 	/ä.Ò.ð	/ús   —AA3 ÁA3 Á3BÂ
Bc           
      óò  —  | j                   d
i |¤Ž}t        d|› d|› d|› d| j                  › �«       | j                  |¬«      }	 t	        j                  «       }| j
                  j                  |t        |«      |¬«       t	        j                  «       }||z
  }| j                  j                  t        j                  |dt        «       › �||¬«       y # t        $ r}t        d	|› �«       Y d }~y d }~ww xY w)NzSet Redis Cache: key: ú
Value ú
ttl=ú, redis_version=rÚ   ©rw   r[   Úexzset_cache <- ©r»   r¼   r½   rÃ   rÄ   z<litellm.caching.caching: set() - Got exception from REDIS : rV   )Úget_ttlr   rœ   ré   rG   r¢   rt   r³   r™   Úservice_success_hookr   rÀ   r3   r,   )	rA   rÛ   r[   rƒ   ÚttlrÃ   rÄ   Ú	_durationr|   s	            r2   rá   zRedisCache.set_cacheØ  sû   € Ø!�T—\‘\Ñ+ FÑ+ˆÜÐ.¨s¨e°8¸E¸7À&ÈÈÐM]Ð^b×^pÑ^pÐ]qÐrÔsØ×*Ñ*¨sÐ*Ó3ˆð	^Ü $§	¡	£ˆJØ×Ñ×!Ñ! s´#°e³*ÀÐ!ÔEÜ"Ÿi™i›kˆHØ'¨*Ñ4ˆIØ×#Ñ#×8Ñ8Ü$×*Ñ*Ø"Ø)Ô*>Ó*@Ð)AÐBØ%Ø!ð 9õ øô ò 	^äÐXÐYZÐX[Ð\×]Ñ]ûð	^ús   ÁBC Ã	C6ÃC1Ã1C6r[   rý   c                 ó  — | j                   }t        j                  «       }| j                  |¬«      }| j                  |¬«      }	 t        j                  «       }|j	                  ||¬«      }t        j                  «       }	|	|z
  }
| j
                  j                  t        j                  |
dt        «       › �||	¬«       |�ôt        j                  «       }|j                  |«      }t        j                  «       }	|	|z
  }
| j
                  j                  t        j                  |
dt        «       › �||	¬«       |dk(  rxt        j                  «       }|j                  ||«       t        j                  «       }	|	|z
  }
| j
                  j                  t        j                  |
dt        «       › �||	¬«       |S # t        $ r@}t        j                  «       }	|	|z
  }
t        j                  d	t        |«      |«       |‚d }~ww xY w)
N©rý   rÚ   ©rw   Úamountzincrement_cache <- rú   zincrement_cache_ttl <- éÿÿÿÿzincrement_cache_expire <- zXLiteLLM Redis Caching: increment_cache() - Got exception from REDIS %s, Writing value=%s)r¢   rG   rû   ré   Úincrr™   rü   r   rÀ   r3   rý   Úexpirer,   r   r®   r³   )rA   rÛ   r[   rý   rƒ   Ú_redis_clientrÃ   Úset_ttlr{   rÄ   rþ   Úcurrent_ttlr|   s                r2   Úincrement_cachezRedisCache.increment_cacheì  sä  € Ø#×0Ñ0ˆÜ—Y‘Y“[ˆ
ØŸ™¨#˜Ó.ˆØ×*Ñ*¨sÐ*Ó3ˆð1	ÜŸ™›ˆJØ!.×!3Ñ!3¸ÀUÐ!3Ó!KˆFÜ—y‘y“{ˆHØ  :Ñ-ˆIØ×#Ñ#×8Ñ8Ü$×*Ñ*Ø"Ø/Ô0DÓ0FÐ/GÐHØ%Ø!ð 9ô ð Ð"ä!ŸY™Y›[�
Ø%2×%6Ñ%6°sÓ%;�ÜŸ9™9›;�Ø$ zÑ1�	Ø×'Ñ'×<Ñ<Ü(×.Ñ.Ø&Ø 7Ô8LÓ8NÐ7OÐPØ)Ø%ð =ô ð  "Ò$ä!%§¡£�JØ!×(Ñ(¨¨gÔ6Ü#Ÿy™y›{�HØ (¨:Ñ 5�IØ×+Ñ+×@Ñ@Ü ,× 2Ñ 2Ø!*Ø$>Ô?SÓ?UÐ>VÐ"WØ#-Ø!)ð Aô ð ˆMøÜò 		ä—y‘y“{ˆHØ  :Ñ-ˆIÜ× Ñ ØjÜ�A“Øôð
 ˆGûð		ús   ÁE0F7 Æ7	H Ç ;G;Ç;H ÚpatternÚcountc              ƒ   ó
  K  — t        j                   «       }	 g }| j                  «       }t        |d«      st        j                  d«       g S | j                  |¬«      }|j                  |dz   |¬«      2 3 d {  –—† }|j                  |«       t        |«      |k\  sŒ) t        j                   «       }||z
  }t        j                  | j                  j                  t        j                  |dt        «       › �||¬«      «       |S 7 ŒŒ6 Œk# t         $ rm}	t        j                   «       }||z
  }t        j                  | j                  j#                  t        j                  ||	dt        «       › �||¬«      «       |	‚d }	~	ww xY w­w)	NÚ	scan_iterz_Redis client does not support scan_iter, potentially using Redis Cluster. Returning empty list.rÚ   Ú*)Úmatchr  zasync_scan_iter <- rú   )r»   r¼   r®   r½   rÃ   rÄ   )rG   rä   r¶   r   r´   ré   r  r*   Úlenri   r²   r™   Úasync_service_success_hookr   rÀ   r3   r,   r¿   )
rA   r
  r  rÃ   Úkeysr  rÛ   rÄ   rþ   r|   s
             r2   Úasync_scan_iterzRedisCache.async_scan_iter$  sˆ  è ø€ ä ŸI™I›Kˆ
ð+	ØˆDØ#'×#9Ñ#9Ó#;ˆMÜ˜=¨+Ô6Ü×$Ñ$Øuôð �	à×2Ñ2°wÐ2Ó?ˆGØ*×4Ñ4¸7ÀS¹=ÐPUÐ4ÓV÷ ð �cØ—‘˜CÔ Ü�t“9 Ó%Øô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø 3Ô4HÓ4JÐ3KÐLØ)Ø%ð Có ôð ˆKð#øÐVùô$ ò 	ô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ 3Ô4HÓ4JÐ3KÐLØ)Ø%ð Có ô	ð ˆGûð	üs`   ‚F˜4D
 ÁFÁ(D
 Á5DÁ9DÁ:DÁ= D
 ÂA'D
 ÄFÄDÄD
 Ä
	F ÄA(E;Å;F Æ FÚscript.c           	      ó@  ‡ ‡‡— d‰ j                  «       › d‰ j                  › dt        j                  ‰j	                  «       «      j                  «       dd › �Š	 d
dt        t           dt        t        t        z  t        z  t        z     dt        dt        fˆˆˆ fd	„}|S )a¹  
        Register a Lua script with Redis asynchronously.
        Works with both standalone Redis and Redis Cluster.

        The returned callable namespaces every key it is invoked with, so Lua
        scripts hit the same prefixed keys as get/set/increment. Without this,
        scripts would operate on raw keys while the rest of the cache uses the
        namespace, leaving rate-limit and lock keys outside the configured prefix.

        Registration is deferred to call time and cached per running event loop
        (via in_memory_llm_clients_cache, which keys its entries on the loop). A
        registered script is bound to the connection of the loop it was created
        on; awaiting it from another loop raises "got Future attached to a
        different loop". Binding lazily on the calling loop gives the script the
        same per-loop scoping init_async_client already gives the clients, so a
        script registered once at startup is never reused across loops.

        Args:
            script (str): The Lua script to register

        Returns:
            A callable ``(keys, args, client=None)`` that runs the script
            against the calling loop's Redis client.
        zredis-registered-script-r]   NrÊ   r  r‚   Úclientr!   c              “   óv   •‡ ‡‡K  — dt         fˆˆˆ ˆˆˆfd„}t        ‰j                  d|«      ƒ d {  –—† S 7 Œ­w)Nr!   c               “   óÞ   •K  — t         j                  j                  ‰¬«      } | €2‰j                  ‰«      } t         j                  j	                  ‰| ¬«        | ‰‰‰¬«      ƒ d {  –—† S 7 Œ­w)NrÚ   rÝ   ©r  r‚   r  )r©   rØ   rÞ   Ú!_register_script_for_current_looprá   )Úexecutorr‚   r  r  r  Úscript_cache_keyrA   s    €€€€€€r2   ÚexecutezERedisCache.async_register_script.<locals>.run_script.<locals>.execute|  sp   øè ø€ ÜAH×AdÑAd×AnÑAnØ(ð Boó B�ð Ð#Ø#×EÑEÀfÓM�HÜ×7Ñ7×AÑAÐFVÐ^fÐAÔgÙ%¨4°dÀ6ÔJ×JÐJÐJús   ƒA#A-Á&A+Á'A-Ú
run_script)Úobjectr}   r†   )r  r‚   r  r  r  r  rA   s   ``` €€€r2   r  z4RedisCache.async_register_script.<locals>.run_scriptw  s9   ûè ø€ ð
K¤6÷ Kò Kô 4°D×4IÑ4IÈ<ÐY`Óa×aÐaÐaús   †,9²7³9r�   )rÖ   rŽ   rÏ   rÐ   rÑ   rÒ   r   r³   ÚbytesrT   rî   r  )rA   r  r  r  s   `` @r2   Úasync_register_scriptz RedisCache.async_register_scriptT  s¥   ú€ ð> ' t×'GÑ'GÓ'IÐ&JÈ!Ø�~‰~Ð˜a¤§¡¨v¯}©}«Ó ?× IÑ IÓ KÈCÈRÐ PÐQðSð 	ð "ñ	bÜœ3‘-ð	bäœ3¤™;¬Ñ,¬uÑ4Ñ5ð	bô ð	bô ÷		bð  ÐrC   c           	      óÎ  ‡ ‡‡‡— ‰ j                  «       Št        ‰d«      rW‰j                  |«      Š	 d
dt        t           dt        t        t
        z  t        z  t        z     dt        dt        fˆˆ fd„}|S t        ‰d«      rX‰j                  |«      Š	 d
dt        t           dt        t        t
        z  t        z  t        z     dt        dt        fˆˆˆ fd„}|S t        d	«      ‚)zê
        Register the script against the current event loop's Redis client.

        Kept separate from async_register_script so each loop caches its own
        executor; see that method for why the binding must be per loop.
        Úregister_scriptr  r‚   r  r!   c              “   ó^   •K  — t        ˆfd„| D «       «      } ‰|||¬«      ƒ d {  –—† S 7 Œ­w)Nc              3   óB   •K  — | ]  }‰j                  |¬ «      –— Œ y­w©rÚ   N©ré   ©Ú.0rÛ   rA   s     €r2   ú	<genexpr>z\RedisCache._register_script_for_current_loop.<locals>.standalone_executor.<locals>.<genexpr>™  ó!   øè ø€ Ò.eÐY\¨t×/KÑ/KÐPSÐ/K×/TÑ.eùó   ƒr  )Útuple)r  r‚   r  Únamespaced_keysÚregistered_scriptrA   s       €€r2   Ústandalone_executorzIRedisCache._register_script_for_current_loop.<locals>.standalone_executor”  s0   øè ø€ ô
 */Ó.eÐ`dÔ.eÓ)e�Ù.°OÈ$ÐW]Ô^×^Ð^Ð^ús   ƒ#-¦+§-Úscript_loadc              “   ó†   •K  — t        ˆfd„| D «       «      } ‰j                  ‰t        |«      g|¢|¢­Ž ƒ d {  –—† S 7 Œ­w)Nc              3   óB   •K  — | ]  }‰j                  |¬ «      –— Œ y­wr&  r'  r(  s     €r2   r*  zYRedisCache._register_script_for_current_loop.<locals>.cluster_executor.<locals>.<genexpr>¦  r+  r,  )r-  Úevalshar  )r  r‚   r  r.  r  Ú
script_sharA   s       €€€r2   Úcluster_executorzFRedisCache._register_script_for_current_loop.<locals>.cluster_executor¡  sF   øè ø€ ô
 */Ó.eÐ`dÔ.eÓ)e�Ø2˜]×2Ñ2°:¼sÀ?Ó?SÐmÐVeÐmÐhlÒm×mÐmÐmús   ƒ7Aº?»Az5Redis client does not support Lua script registrationr�   )rä   r¶   r#  r   r³   r   rT   rî   r  r1  rï   )rA   r  r0  r6  r  r/  r5  s   `   @@@r2   r  z,RedisCache._register_script_for_current_loop‰  sù   û€ ð %)×$:Ñ$:Ó$<ˆÜ�=Ð"3Ô4Ø'4×'DÑ'DÀVÓ'LÐð
 "&ñ_Üœs‘mð_äœs¤U™{¬SÑ0´5Ñ8Ñ9ð_ô ð_ô ö	_ð 'Ð&ä�= -Ô0Ø -× 9Ñ 9¸&Ó AˆJð
 "&ñnÜœs‘mðnäœs¤U™{¬SÑ0´5Ñ8Ñ9ðnô ðnô ÷	nð $Ð#äÐPÓQÐQrC   c              ‹   ó’  K  — ddl m} |€t        j                  d|«       y t	        j                  «       }	 | j                  «       }| j#                  |¬«      } | j$                  di |¤Ž}
|j'                  dd	«      }t)        d
|› d|› d|
› �«       	 t+        |d«      st        d«      ‚|j-                  |t/        j0                  |«      ||
¬«      ƒ d {  –—† }t)        d|› d|› d|
› �«       t	        j                  «       }||z
  }	t        j                  | j                  j3                  t        j                  |	dt        «       › �||t        |«      d|i¬«      «       |S # t        $ r˜}t	        j                  «       }||z
  }	t        j                  | j                  j                  t        j                  |	|||t        |«      dt        «       › �¬«      «       t        j                  dt!        |«      ||«       |‚d }~ww xY w7 �Œ1# t        $ r³}t	        j                  «       }||z
  }	t        j                  | j                  j                  t        j                  |	|dt        «       › �||t        |«      d|i¬«      «       t        j                  dt!        |«      |«       t5        | j6                  |«       Y d }~y d }~ww xY w­w)Nr   ©r   uD   LiteLLM Redis Caching: async set() skipped â€” key is None, value=%rzasync_set_cache <- ©r»   r¼   r®   rÃ   rÄ   Úparent_otel_spanr½   zRLiteLLM Redis Caching: async set() - Got exception from REDIS %s, key=%r, value=%rrÚ   ÚnxFúSet ASYNC Redis Cache: key: rõ   rö   rt   z3Redis client cannot set cache. Attribute not found.)rw   r[   r;  rù   z)Successfully Set ASYNC Redis Cache: key: rÛ   ©r»   r¼   r½   rÃ   rÄ   r:  Úevent_metadata©r»   r¼   r®   r½   rÃ   rÄ   r:  r>  úRLiteLLM Redis Caching: async set() - Got exception from REDIS %s, Writing value=%srV   )Úredis.asyncior   r   r´   rG   rä   r,   ri   r²   r™   r¿   r   rÀ   r   r3   r®   r³   ré   rû   ru   r   r¶   rt   rÍ   rÎ   r  rv   r†   )rA   rÛ   r[   rƒ   r   rÃ   r  r|   rÄ   rþ   rý   r;  r{   s                r2   Úasync_set_cachezRedisCache.async_set_cache­  sØ  è ø€ å'àˆ;Ü× Ñ ØVØôð ä ŸI™I›Kˆ
ð	Ø*.×*@Ñ*@Ó*BˆMð. ×*Ñ*¨sÐ*Ó3ˆØ!�T—\‘\Ñ+ FÑ+ˆØ—J‘J˜t UÓ+ˆÜÐ4°S°E¸À%ÀÈÈsÈeÐTÔUð,	FÜ˜=¨%Ô0ÜÐ UÓVÐVØ"/×"3Ñ"3ØÜ—j‘j Ó'ØØð	 #4ó #÷ ˆFô ÐEÀcÀUÈ(ÐSXÐRYÐY_Ð`cÐ_dÐeÔfÜ—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø 3Ô4HÓ4JÐ3KÐLØ)Ø%Ü%FÀvÓ%NØ$)¨3 <ð Có ô
ð ˆMøôe ò 	Ü—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ)Ø%Ü%FÀvÓ%NØ 3Ô4HÓ4JÐ3KÐLð Có ô
ô × Ñ ØdÜ�A“ØØô	ð ˆGûð)	úð<úô* ò 	FÜ—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ 3Ô4HÓ4JÐ3KÐLØ)Ø%Ü%FÀvÓ%NØ$)¨3 <ð Có 	ôô × Ñ ØdÜ�A“Øôô
 ,¨D×,AÑ,AÀ1×EÑEûð)	Füsi   ‚4K·E! ÁA
KÂAH ÃHÃBH Å KÅ!	HÅ*BG=Ç=HÈKÈH È	KÈB)J?Ê:KÊ?KËKÚpipeÚ
cache_listc           	   ƒ   ó8  K  — | j                  |¬«      }|D ]d  \  }}| j                  |¬«      }t        d|› d|› d|› �«       t        j                  |«      }d}|�t        |¬«      }|j                  |||¬«       Œf |j                  «       ƒ d{  –—† }|S 7 Œ­w)	zU
        Helper function for executing a pipeline of set operations on Redis
        r   rÚ   z%Set ASYNC Redis Cache PIPELINE: key: rõ   rö   N©Úsecondsrø   )rû   ré   r   rÍ   rÎ   r   rt   r  )	rA   rC  rD  rý   râ   Úcache_valueÚjson_cache_valueÚ_tdÚresultss	            r2   Ú_pipeline_helperzRedisCache._pipeline_helper  s·   è ø€ ð �l‰l˜sˆlÓ#ˆà&0ò 	Ñ"ˆI�{Ø×4Ñ4¸Ð4ÓCˆIÜÐAÀ)ÀÈHÐU`ÐTaÐagÐhkÐglÐmÔnÜ#Ÿz™z¨+Ó6Ðà$(ˆCØˆÜ¨Ô,�Ø�H‰HØØ&Øð õ ð	ð  $Ÿ|™|›~×-ˆØˆð .ús   ‚BBÂBÂBc              ‹   óè  K  — t        |«      dk(  ry| j                  «       }t        j                  «       }t        d|› d|› d| j                  › �«       d}	 |j                  d¬«      4 ƒd{  –—† }| j                  |||«      ƒ d{  –—† }ddd«      ƒd{  –—†  t        d› �«       t        j                  «       }	|	|z
  }
t        j                  | j                  j                  t        j                  |
d	t        «       › �||	t        |«      ¬
«      «       y7 Œ­7 Œ”7 Œ†# 1 ƒd{  –—†7  sw Y   Œ–xY w# t        $ r°}t        j                  «       }	|	|z
  }
t        j                  | j                  j!                  t        j                  |
|d	t        «       › �||	t        |«      ¬«      «       t#        j$                  dt'        |«      |«       t)        | j*                  |«       Y d}~yd}~ww xY w­w)z?
        Use Redis Pipelines for bulk write operations
        r   Nz!Set Async Redis Cache: key list: rö   r÷   F©Útransactionzpipeline results: zasync_set_cache_pipeline <- ©r»   r¼   r½   rÃ   rÄ   r:  ©r»   r¼   r®   r½   rÃ   rÄ   r:  zaLiteLLM Redis Caching: async set_cache_pipeline() - Got exception from REDIS %s, Writing value=%s)r  rä   rG   r   rœ   ÚpipelinerL  ri   r²   r™   r  r   rÀ   r3   r   r,   r¿   r   r®   r³   rv   r†   )rA   rD  rý   rƒ   r  rÃ   rH  rC  rK  rÄ   rþ   r|   s               r2   Úasync_set_cache_pipelinez#RedisCache.async_set_cache_pipeline   só  è ø€ ô ˆz‹?˜aÒØà#×5Ñ5Ó7ˆÜ ŸI™I›Kˆ
äÐ9¸*¸ÀVÈCÈ5ÐP`Ðae×asÑasÐ`tÐuÔvØ!ˆð)	FØ$×-Ñ-¸%Ð-Ó@÷ Tð TÀDØ'+×'<Ñ'<¸TÀ:ÈsÓ'S×!S�÷T÷ Tô Ð.¨w¨iÐ8Ô9ô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø <Ô=QÓ=SÐ<TÐUØ)Ø%Ü%FÀvÓ%Nð Có ô	ð ð%TøØ!SøðTø÷ T÷ Tñ Tûô& ò 	Fä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ <Ô=QÓ=SÐ<TÐUØ)Ø%Ü%FÀvÓ%Nð Có ô
ô × Ñ ØsÜ�A“Øôô
 ,¨D×,AÑ,AÀ1×EÑEûð+	FüsŒ   ‚AG2ÁD6 Á-DÁ.D6 Á1D!ÂDÂ	D!ÂD6 ÂDÂBD6 ÄG2ÄD6 ÄD!ÄD6 Ä!D3Ä'D*Ä(D3Ä/D6 Ä6	G/Ä?B&G*Ç%G2Ç*G/Ç/G2r¢   c              ƒ   óÞ   K  — | j                  |¬«      }	  |j                  |g|¢­Ž ƒ d{  –—†  |�'t        |¬«      }|j                  ||«      ƒ d{  –—†  yy7 Œ.7 Œ# t        $ r ‚ w xY w­w)z@Helper function for async_set_cache_sadd. Separated for testing.r   NrF  )rû   Úsaddr   r  r,   )rA   r¢   rÛ   r[   rý   rJ  s         r2   Ú_set_cache_sadd_helperz!RedisCache._set_cache_sadd_helper[  s~   è ø€ ð �l‰l˜sˆlÓ#ˆð	Ø#�,×#Ñ# CÐ0¨%Ò0×0Ð0ØˆÜ&¨sÔ3�Ø"×)Ñ)¨#¨sÓ3×3Ñ3ð ð 1øð 4ùÜò 	Øð	üs>   ‚A-–A ¬A­'A ÁAÁA ÁA-ÁA ÁA ÁA*Á*A-c              ‹   ó´  K  — ddl m} t        j                  «       }	 | j                  «       }| j!                  |¬«      }t#        d|› d|› d	|› �«       	 | j%                  ||||¬
«      ƒ d {  –—†  t#        d|› d|› d	|› �«       t        j                  «       }	|	|z
  }
t        j                  | j                  j'                  t        j                  |
dt        «       › �||	t        |«      ¬«      «       y # t        $ r—}t        j                  «       }	|	|z
  }
t        j                  | j                  j                  t        j                  |
|||	t        |«      dt        «       › �¬«      «       t        j                  dt        |«      |«       |‚d }~ww xY w7 �Œ,# t        $ r°}t        j                  «       }	|	|z
  }
t        j                  | j                  j                  t        j                  |
|dt        «       › �||	t        |«      ¬«      «       t        j                  dt        |«      |«       t)        | j*                  |«       Y d }~y d }~ww xY w­w)Nr   r8  zasync_set_cache_sadd <- r9  r@  rÚ   r<  rõ   rö   )r¢   rÛ   r[   rý   z.Successfully Set ASYNC Redis Cache SADD: key: rP  rQ  z]LiteLLM Redis Caching: async set_cache_sadd() - Got exception from REDIS %s, Writing value=%s)rA  r   rG   rä   r,   ri   r²   r™   r¿   r   rÀ   r   r3   r   r®   r³   ré   r   rV  r  rv   r†   )rA   rÛ   r[   rý   rƒ   r   rÃ   r  r|   rÄ   rþ   s              r2   Úasync_set_cache_saddzRedisCache.async_set_cache_saddl  sW  è ø€ å'ä ŸI™I›Kˆ
ð	Ø*.×*@Ñ*@Ó*BˆMð. ×*Ñ*¨sÐ*Ó3ˆÜÐ4°S°E¸À%ÀÈÈsÈeÐTÔUð#	FØ×-Ñ-¸=ÈcÐY^ÐdgÐ-Óh×hÐhÜÐJÈ3È%ÈxÐX]ÐW^Ð^dÐehÐdiÐjÔkÜ—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø 8Ô9MÓ9OÐ8PÐQØ)Ø%Ü%FÀvÓ%Nð Có õ	øô; ò 	Ü—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ)Ø%Ü%FÀvÓ%NØ 8Ô9MÓ9OÐ8PÐQð Có ô
ô × Ñ ØdÜ�A“Øôð
 ˆGûð)	úð2 iúô ò 	FÜ—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ 8Ô9MÓ9OÐ8PÐQØ)Ø%Ü%FÀvÓ%Nð Có ô
ô × Ñ ØoÜ�A“Øôô
 ,¨D×,AÑ,AÀ1×EÑEûð)	Füsf   ‚IžC6 ®&IÁF Á-FÁ.BF Ã5IÃ6	FÃ?BFÆFÆIÆF Æ	IÆ%B&IÉIÉIÉIc              ‹   ó&  K  — t        dt        | j                  «      › �«       | j                  |¬«      }| j                  j	                  ||f«       t        | j                  «      | j
                  k\  r| j                  «       ƒ d {  –—†  y y 7 Œ­w)Nz-in batch cache writing for redis buffer size=rÚ   )r   r  r¦   ré   r*   r�   Úflush_cache_buffer)rA   rÛ   r[   rƒ   s       r2   Úbatch_cache_writezRedisCache.batch_cache_write°  s…   è ø€ äØ;¼CÀ×@_Ñ@_Ó<`Ð;aÐbô	
ð ×*Ñ*¨sÐ*Ó3ˆØ×'Ñ'×.Ñ.°°U¨|Ô<Üˆt×.Ñ.Ó/°4×3HÑ3HÒHØ×)Ñ)Ó+×+Ñ+ð IØ+ús   ‚BBÂBÂ	Br:  Úrefresh_ttlc              ƒ   ó   K  — ddl m} | j                  «       }t        j                  «       }| j	                  |¬«      }	| j                  |¬«      }	 |j                  ||¬«      ƒ d {  –—† }
|	�U|r|j                  ||	«      ƒ d {  –—†  n8|j                  |«      ƒ d {  –—† }|dk(  r|j                  ||	«      ƒ d {  –—†  t        j                  «       }||z
  }t        j                  | j                  j                  t        j                  |dt        «       › �|||¬«      «       |
S 7 ŒÃ7 Œ§7 Œ�7 Œr# t         $ rŽ}t        j                  «       }||z
  }t        j                  | j                  j#                  t        j                  ||dt        «       › �|||¬	«      «       t%        j&                  d
t)        |«      |«       |‚d }~ww xY w­w)Nr   r8  r   rÚ   r  r  zasync_increment <- rP  rQ  z^LiteLLM Redis Caching: async async_increment() - Got exception from REDIS %s, Writing value=%s)rA  r   rä   rG   rû   ré   Úincrbyfloatr  rý   ri   r²   r™   r  r   rÀ   r3   r,   r¿   r   r®   r³   )rA   rÛ   r[   rý   r:  r\  r   r  rÃ   Ú	_used_ttlr{   r  rÄ   rþ   r|   s                  r2   Úasync_incrementzRedisCache.async_incrementº  sË  è ø€ õ 	(à&*×&<Ñ&<Ó&>ˆÜ ŸI™I›Kˆ
ØŸ<™<¨C˜<Ó0ˆ	Ø×*Ñ*¨sÐ*Ó3ˆð-	Ø"/×";Ñ";ÀÈUÐ";Ó"S×SˆFØÐ$ÙØ'×.Ñ.¨s°IÓ>×>Ñ>à/<×/@Ñ/@ÀÓ/E×)E�KØ" bÒ(Ø+×2Ñ2°3¸	ÓB×BÐBô —y‘y“{ˆHØ  :Ñ-ˆIä×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø 3Ô4HÓ4JÐ3KÐLØ)Ø%Ø%5ð Có ô	ð ˆMð/ Tøð ?øà)EøàBùô" ò 	ä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ 3Ô4HÓ4JÐ3KÐLØ)Ø%Ø%5ð Có ô
ô × Ñ ØpÜ�A“Øôð
 ˆGûð)	üst   ‚AGÁD4 Á(D,Á)D4 ÂD.ÂD4 Â D0Â!D4 Â?D2Ã A+D4 Ä+GÄ,D4 Ä.D4 Ä0D4 Ä2D4 Ä4	GÄ=B	GÇGÇGc              ƒ   ób  K  — | j                  «       }| j                  |¬«      }| j                  |¬«      }d}t        d|j	                  |d|t        |«      t        t        |xs d«      «      «      ƒ d{  –—† «      }|€yt        |t        «      r|j                  «       }t        |«      S 7 Œ6­w)a  Atomically set ``key`` to ``value`` only when ``value`` is greater
        than the stored value (or the key is unset), refreshing the TTL.

        Monotonic by construction: it never lowers the stored value, so a repair
        that writes an authoritative-but-slightly-stale total cannot clobber a
        concurrent increment that has already pushed the counter higher. The
        GET/compare/SET runs in a single Lua call, so it is also atomic across
        racing callers and pods. Returns the resulting value.
        r   rÚ   zëlocal cur = redis.call('GET', KEYS[1]) if cur == false or tonumber(cur) < tonumber(ARGV[1]) then redis.call('SET', KEYS[1], ARGV[1]) if tonumber(ARGV[2]) > 0 then redis.call('EXPIRE', KEYS[1], ARGV[2]) end return ARGV[1] end return curz str | bytes | int | float | Noner   r   N)rä   rû   ré   r   Úevalr³   rT   ro   r   Údecoderî   )rA   rÛ   r[   rý   r  r_  Úluar{   s           r2   Úasync_set_maxzRedisCache.async_set_maxø  s­   è ø€ ð   $×5Ñ5Ó7ˆØŸ<™<¨C˜<Ó0ˆ	Ø×*Ñ*¨sÐ*Ó3ˆðð 	ô Ø.Ø×$Ñ$ S¨!¨S´#°e³*¼cÄ#ÀiÂnÐSTÓBUÓ>VÓW×Wó
ˆð ˆ>ØÜ�fœeÔ$Ø—]‘]“_ˆFÜ�V‹}Ðð Xús   ‚A4B/Á6B-
Á77B/c              ƒ   ó¦   K  — t        dt        | j                  «      › �«       | j                  | j                  «      ƒ d {  –—†  g | _        y 7 Œ­w)Nz,flushing to redis....reached size of buffer )r   r  r¦   rS  rH   s    r2   rZ  zRedisCache.flush_cache_buffer  sJ   è ø€ ÜÐDÄSÈ×IhÑIhÓEiÐDjÐkÔlØ×+Ñ+¨D×,KÑ,KÓL×LÐLØ*,ˆÕ'ð 	Mús   ‚A AÁAÁAÚcached_responsec                 ó¦   — |€|S |j                  d«      }	 t        j                  |«      }|S # t        $ r t	        j
                  |«      }Y |S w xY w)z[
        Common 'get_cache_logic' across sync + async redis client implementations
        úutf-8)rc  rÍ   Úloadsr,   ÚastÚliteral_eval)rA   rg  s     r2   Ú_get_cache_logiczRedisCache._get_cache_logic"  se   € ð Ð"Ø"Ð"à)×0Ñ0°Ó9ˆð	@Ü"Ÿj™j¨Ó9ˆOð Ðøô ò 	@Ü!×.Ñ.¨Ó?‰OØÐð	@ús   —. ®AÁAc                 óæ  — 	 | j                  |¬«      }t        d|› �«       t        j                  «       }| j                  j	                  |«      }t        j                  «       }||z
  }| j
                  j                  t        j                  |dt        «       › �|||¬«       t        d|› d|› �«       | j                  |¬«      S # t        $ r }t        j                  d|«       Y d }~y d }~ww xY w)	NrÚ   zGet Redis Cache: key: zget_cache <- rP  zGot Redis Cache: key: ú, cached_response ©rg  z;litellm.caching.caching: get() - Got exception from REDIS: )ré   r   rG   r¢   ru   r™   rü   r   rÀ   r3   rm  r,   r   r®   )	rA   rÛ   r:  rƒ   rÃ   rg  rÄ   rþ   r|   s	            r2   rÞ   zRedisCache.get_cache0  só   € ð	cØ×.Ñ.°3Ð.Ó7ˆCÜÐ2°3°%Ð8Ô9Ü $§	¡	£ˆJØ%)×%6Ñ%6×%:Ñ%:¸3Ó%?ˆOÜ"Ÿi™i›kˆHØ'¨*Ñ4ˆIØ×#Ñ#×8Ñ8Ü$×*Ñ*Ø"Ø)Ô*>Ó*@Ð)AÐBØ%Ø!Ø!1ð 9ô ô Ð2°3°%Ð7IÈ/ÐIZÐ[Ô\Ø×(Ñ(¸Ð(ÓIÐIøÜò 	cä× Ñ Ð!^Ð`a×bÑbûð	cús   ‚CC Ã	C0ÃC+Ã+C0r  c                 ó:   — | j                   j                  |¬«      S )ú
        Wrapper to call `mget` on the redis client

        We use a wrapper so RedisCluster can override this method
        ©r  )r¢   Úmget)rA   r  s     r2   Ú_run_redis_mget_operationz$RedisCache._run_redis_mget_operationF  s   € ð × Ñ ×%Ñ%¨4Ð%Ó0Ð0rC   c              ƒ   ób   K  — | j                  «       }|j                  |¬«      ƒ d{  –—† S 7 Œ­w)rr  rs  N)rä   rt  )rA   r  rß   s      r2   Ú_async_run_redis_mget_operationz*RedisCache._async_run_redis_mget_operationN  s1   è ø€ ð %)×$:Ñ$:Ó$<ÐØ'×,Ñ,°$Ð,Ó7×7Ð7Ð7ús   ‚&/¨-©/Úkey_listc                 ó´  — i }|D �cg c]  }|€Œ|‘Œ	 }}	 g }|D ])  }| j                  |xs d¬«      }|j                  |«       Œ+ t        j                  «       }| j                  |¬«      }	t        j                  «       }
|
|z
  }| j                  j                  t        j                  |dt        «       › �||
|¬«       t        t        ||	«      «      }i }|j                  «       D ]<  \  }}t        |t        «      r|j                  d«      }| j                  |«      }|||<   Œ> |S c c}w # t         $ r"}t#        j$                  d|«       |cY d}~S d}~ww xY w)	a  
        Use Redis for bulk read operations

        Args:
            key_list: List of keys to get from Redis
            parent_otel_span: Optional parent OpenTelemetry span

        Returns:
            dict: A dictionary mapping keys to their cached values
        NÚ rÚ   rs  zbatch_get_cache <- rP  ri  z&Error occurred in batch get cache - %s)ré   r*   rG   ru  r™   rü   r   rÀ   r3   ÚdictÚziprÌ   ro   r   rc  rm  r,   r   r®   )rA   rx  r:  Úkey_value_dictrÛ   Ú	_key_listÚ_keysrâ   rÃ   rK  rÄ   rþ   Údecoded_resultsÚkÚvr|   s                   r2   Úbatch_get_cachezRedisCache.batch_get_cacheW  sl  € ð ˆØ+3ÖG C°s±šCÐGˆ	ÐGð 	"ØˆEØ&ò (�	Ø ×8Ñ8¸Yº_È"Ð8ÓM�	Ø—‘˜YÕ'ð(ô !%§	¡	£ˆJØ!×;Ñ;ÀÐ;ÓGˆGÜ"Ÿi™i›kˆHØ'¨*Ñ4ˆIØ×#Ñ#×8Ñ8Ü$×*Ñ*Ø"Ø/Ô0DÓ0FÐ/GÐHØ%Ø!Ø!1ð 9ô ô "¤# i°Ó"9Ó:ˆNà%'ˆOØ&×,Ñ,Ó.ò '‘��1Ü˜a¤Ô'ØŸ™ Ó)�AØ×)Ñ)¨!Ó,�Ø%&� Ò"ð	'ð #Ð"ùò? Høô@ ò 	"Ü× Ñ Ð!IÈ1ÔMØ!Õ!ûð	"ús(   ‡D'�D'–DD, Ä,	EÄ5EÅEÅEc              ‹   ó:  K  — ddl m} | j                  «       }| j                  |¬«      }t	        j                  «       }	 t        d|› �«       |j                  |«      ƒ d {  –—† }t        d|› d|› �«       | j                  |¬«      }t	        j                  «       }	|	|z
  }
t        j                  | j                  j                  t        j                  |
dt        «       › �||	|d	|i¬
«      «       |S 7 Œ’# t        $ r˜}t	        j                  «       }	|	|z
  }
t        j                  | j                  j!                  t        j                  |
|dt        «       › �||	|d	|i¬«      «       t        d|› �«       t#        | j$                  |«       Y d }~y d }~ww xY w­w)Nr   r8  rÚ   zGet Async Redis Cache: key: zGot Async Redis Cache: key: ro  rp  zasync_get_cache <- rÛ   r=  r?  zAlitellm.caching.caching: async get() - Got exception from REDIS: )rA  r   rä   ré   rG   r   ru   rm  ri   r²   r™   r  r   rÀ   r3   r,   r¿   rv   r†   )rA   rÛ   r:  rƒ   r   r  rÃ   rg  ÚresponserÄ   rþ   r|   s               r2   Úasync_get_cachezRedisCache.async_get_cache‹  s¤  è ø€ å'à&*×&<Ñ&<Ó&>ˆØ×*Ñ*¨sÐ*Ó3ˆÜ ŸI™I›Kˆ
ð$	FÜÐ8¸¸Ð>Ô?Ø+8×+<Ñ+<¸SÓ+A×%AˆOÜÐ8¸¸Ð=OÐP_ÐO`ÐaÔbØ"×3Ñ3ÀOÐ3ÓTˆHä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø 3Ô4HÓ4JÐ3KÐLØ)Ø%Ø%5Ø$)¨3 <ð Có ô
ð ˆOð# &Bùô$ ò 	FÜ—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ 3Ô4HÓ4JÐ3KÐLØ)Ø%Ø%5Ø$)¨3 <ð Có 	ôô Ð]Ð^_Ð]`ÐaÔbÜ+¨D×,AÑ,AÀ1×EÑEûð!	FüsC   ‚=FÁ "C7 Á"C5Á#BC7 Ã4FÃ5C7 Ã7	FÄ BFÆFÆFÆFc              ƒ   óè  K  — i }t        j                   «       }|D �cg c]  }|€Œ|‘Œ	 }}	 g }|D ]%  }| j                  |¬«      }|j                  |«       Œ' | j                  |¬«      ƒ d{  –—† }	t        j                   «       }
|
|z
  }t	        j
                  | j                  j                  t        j                  |dt        «       › �||
|¬«      «       t        t        ||	«      «      }i }|j                  «       D ]<  \  }}t        |t        «      r|j!                  d«      }| j#                  |«      }|||<   Œ> |S c c}w 7 Œ×# t$        $ rŸ}t        j                   «       }
|
|z
  }t	        j
                  | j                  j'                  t        j                  ||dt        «       › �||
|¬«      «       t)        j*                  d|«       t-        | j.                  |«       |cY d}~S d}~ww xY w­w)	a[  
        Use Redis for bulk read operations

        Args:
            key_list: List of keys to get from Redis
            parent_otel_span: Optional parent OpenTelemetry span

        Returns:
            dict: A dictionary mapping keys to their cached values

        `.mget` does not support None keys. This will filter out None keys.
        NrÚ   rs  zasync_batch_get_cache <- rP  ri  rQ  z,Error occurred in async batch get cache - %s)rG   ré   r*   rw  ri   r²   r™   r  r   rÀ   r3   r{  r|  rÌ   ro   r   rc  rm  r,   r¿   r   r®   rv   r†   )rA   rx  r:  r}  rÃ   rÛ   r~  r  râ   rK  rÄ   rþ   r€  r�  r‚  r|   s                   r2   Úasync_batch_get_cachez RedisCache.async_batch_get_cache¹  sú  è ø€ ð& ˆÜ ŸI™I›Kˆ
Ø+3ÖG C°s±šCÐGˆ	ÐGð1	"ØˆEØ&ò (�	Ø ×8Ñ8¸YÐ8ÓG�	Ø—‘˜YÕ'ð(ð $(×#GÑ#GÈUÐ#GÓ#S×SˆGä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø 9Ô:NÓ:PÐ9QÐRØ)Ø%Ø%5ð Có ô	ô "¤# i°Ó"9Ó:ˆNà%'ˆOØ&×,Ñ,Ó.ò '‘��1Ü˜a¤Ô'ØŸ™ Ó)�AØ×)Ñ)¨!Ó,�Ø%&� Ò"ð	'ð #Ð"ùòA Hð Tùô6 ò 	"ä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ 9Ô:NÓ:PÐ9QÐRØ)Ø%Ø%5ð Có ô
ô × Ñ Ð!OÐQRÔSÜ+¨D×,AÑ,AÀ1ÔEØ!Õ!ûð#	"üsX   ‚G2�E ¥E ©G2¬AE Á-EÁ.CE Ä?G2ÅE Å	G/ÅBG*Ç$G/Ç%G2Ç*G/Ç/G2c           	      ó.  — t        d«       t        j                  «       }	 | j                  j                  «       }t        d|› �«       t        j                  «       }||z
  }| j                  j                  t        j                  |dt        «       › �||¬«       |S # t        $ rn}t        j                  «       }||z
  }| j                  j                  t        j                  ||dt        «       › �¬«       t        j                  d|«       |‚d}~ww xY w)zD
        Tests if the sync redis client is correctly setup.
        zPinging Sync Redis CachezRedis Cache PING: zsync_ping <- rú   rº   ú9LiteLLM Redis Cache PING: - Got exception from REDIS : %sN)r   rG   r¢   r°   r™   rü   r   rÀ   r3   r,   Úservice_failure_hookr   r®   )rA   rÃ   r…  rÄ   rþ   r|   s         r2   Ú	sync_pingzRedisCache.sync_ping  s  € ô 	Ð0Ô1Ü ŸI™I›Kˆ
ð	Ø$(×$5Ñ$5×$:Ñ$:Ó$<ˆHÜÐ.¨x¨jÐ9Ô:ä—y‘y“{ˆHØ  :Ñ-ˆIØ×#Ñ#×8Ñ8Ü$×*Ñ*Ø"Ø)Ô*>Ó*@Ð)AÐBØ%Ø!ð 9ô ð ˆOøÜò 	ô —y‘y“{ˆHØ  :Ñ-ˆIØ×#Ñ#×8Ñ8Ü$×*Ñ*Ø"ØØ)Ô*>Ó*@Ð)AÐBð	 9ô ô × Ñ Ð!\Ð^_Ô`ØˆGûð	ús   ¡A;B Â	DÂ&A)DÄDc              ƒ   ó‚  K  — | j                  «       }t        j                  «       }t        d«       	 |j                  «       ƒ d {  –—† }t        j                  «       }||z
  }t	        j
                  | j                  j                  t        j                  |dt        «       › �¬«      «       |S 7 Œi# t        $ r�}t        j                  «       }||z
  }t	        j
                  | j                  j                  t        j                  ||dt        «       › �¬«      «       t        j                  d|«       |‚d }~ww xY w­w)NzPinging Async Redis Cachezasync_ping <- ©r»   r¼   r½   rº   rŠ  )rä   rG   r   r°   ri   r²   r™   r  r   rÀ   r3   r,   r¿   r   r®   )rA   r  rÃ   r…  rÄ   rþ   r|   s          r2   r°   zRedisCache.ping$  s)  è ø€ à$(×$:Ñ$:Ó$<ˆÜ ŸI™I›Kˆ
ÜÐ1Ô2ð	Ø$1×$6Ñ$6Ó$8×8ˆHä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø .Ô/CÓ/EÐ.FÐGð Có ôð ˆOð 9ùô ò 	ô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ .Ô/CÓ/EÐ.FÐGð	 Có ôô × Ñ Ð!\Ð^_Ô`ØˆGûð	üs<   ‚0D?³B2 ÁB0ÁA(B2 Â/D?Â0B2 Â2	D<Â;A<D7Ä7D<Ä<D?c              ƒ   ó¦   K  — | j                  «       }|D �cg c]  }| j                  |¬«      ‘Œ }} |j                  |Ž ƒ d {  –—†  y c c}w 7 Œ
­w©NrÚ   ©rä   ré   Údelete)rA   r  r  rÛ   s       r2   Údelete_cache_keyszRedisCache.delete_cache_keysF  sV   è ø€ ð %)×$:Ñ$:Ó$<ˆØAEÖF¸#�×,Ñ,°Ð,Õ5ÐFˆÐFà"ˆm×"Ñ" DÐ)×)Ñ)ùò Gà)ús   ‚A—A
°AÁAÁAc                 ó:   — | j                   j                  «       }|S r�   )r¢   Úclient_list)rA   r•  s     r2   r•  zRedisCache.client_listN  s   € Ø#'×#4Ñ#4×#@Ñ#@Ó#BˆØÐrC   c                 ó:   — | j                   j                  «       }|S r�   )r¢   rN   )rA   rN   s     r2   rN   zRedisCache.infoR  s   € Ø×'Ñ'×,Ñ,Ó.ˆØˆrC   c                 ó8   — | j                   j                  «        y r�   ©r¢   ÚflushallrH   s    r2   Úflush_cachezRedisCache.flush_cacheV  ó   € Ø×Ñ×"Ñ"Õ$rC   c                 ó8   — | j                   j                  «        y r�   r˜  rH   s    r2   r™  zRedisCache.flushallY  r›  rC   c              ƒ   óæ   K  — | j                   j                  d¬«      ƒ d {  –—†  	 | j                  j                  «        y 7 Œ # t        $ r }t        j                  d|«       Y d }~y d }~ww xY w­w)NT)Úinuse_connectionsz#Error closing sync Redis client: %s)r¥   Ú
disconnectr¢   Úcloser,   r   r´   )rA   r|   s     r2   rŸ  zRedisCache.disconnect\  sh   è ø€ Ø×(Ñ(×3Ñ3ÀdÐ3ÓK×KÐKð	KØ×Ñ×#Ñ#Õ%ð 	Lùô ò 	KÜ× Ñ Ð!FÈ×JÑJûð	Küs8   ‚ A1¢A£A1¨A ÁA1Á	A.ÁA)Á$A1Á)A.Á.A1c              ƒ   ó8  K  — 	 ddl m}  |di | j                  ¤Ž}|j                  «       ƒ d{  –—† }|j	                  «       ƒ d{  –—†  |rdddœS dddœS 7 Œ(7 Œ# t
        $ r2}t        j                  d	|«       dd
|› �t        |«      dœcY d}~S d}~ww xY w­w)aQ  
        Test the Redis connection by creating a new client and pinging it.

        This creates a fresh connection without using cached clients or connection pools
        to ensure the credentials are actually valid.

        Returns:
            dict: {"status": "success" | "failed", "message": str, "error": Optional[str]}
        r“   )rÙ   NÚsuccessz Redis connection test successful)ÚstatusÚmessageÚfailedzRedis ping returned Falsez Redis connection test failed: %szRedis connection failed: )r£  r¤  r®   rV   )	rŸ   rÙ   r¤   r°   Úacloser,   r   r®   r³   )rA   rÙ   r¢   Úping_resultr|   s        r2   Útest_connectionzRedisCache.test_connectionc  s¶   è ø€ ð	Ý7ñ #9Ñ"M¸4×;LÑ;LÑ"MˆLð (4×'8Ñ'8Ó':×!:ˆKð ×%Ñ%Ó'×'Ð'áà'ØAñð ð
 #+Ð7RÑSÐSð ";øð (ùô ò 	Ü× Ñ Ð!CÀQÔGà"Ø6°q°cÐ:Ü˜Q›ñõ ûð	üsb   ‚B„+A ¯A°A ÁAÁ
A ÁBÁA ÁBÁA ÁA Á	BÁ%'BÂBÂBÂBÂBc              ƒ   ó„   K  — | j                  «       }| j                  |¬«      }|j                  |«      ƒ d {  –—† S 7 Œ­wr�  r‘  )rA   rÛ   r  s      r2   Úasync_delete_cachezRedisCache.async_delete_cacheˆ  s@   è ø€ ð %)×$:Ñ$:Ó$<ˆØ×*Ñ*¨sÐ*Ó3ˆà"×)Ñ)¨#Ó.×.Ð.Ð.ús   ‚7A ¹>ºA c                 ó^   — | j                  |¬«      }| j                  j                  |«       y r�  )ré   r¢   r’  rè   s     r2   Údelete_cachezRedisCache.delete_cache�  s)   € Ø×*Ñ*¨sÐ*Ó3ˆØ×Ñ× Ñ  Õ%rC   Úincrement_listc           
   ƒ   óš  K  — |D ]m  }| j                  |d   ¬«      }t        d|› d|d   › d|d   › �«       |j                  ||d   «       |d   €ŒMt        |d   ¬	«      }|j	                  ||«       Œo |j                  «       ƒ d{  –—† }t        j                  d
|«       |D �cg c]  }t        |t        «      sŒ|‘Œ c}S 7 Œ;c c}w ­w)z1Helper function for pipeline increment operationsrÛ   rÚ   z+Increment ASYNC Redis Cache PIPELINE: key: rõ   Úincrement_valuerö   rý   NrF  z1Increment ASYNC Redis Cache PIPELINE: results: %s)
ré   r   r^  r   r  r  r   r´   ro   rî   )rA   rC  r­  Úincrement_oprâ   rJ  rK  Úrs           r2   Ú_pipeline_increment_helperz%RedisCache._pipeline_increment_helper”  s÷   è ø€ ð +ò 	,ˆLØ×4Ñ4¸ÀeÑ9LÐ4ÓMˆIÜØ=¸i¸[ÈÐQ]Ð^oÑQpÐPqÐqwð  yEð  FKñ  yLð  xMð  Nôð ×Ñ˜Y¨Ð5FÑ(GÔHØ˜EÑ"Ñ.Ü¨°UÑ(;Ô<�Ø—‘˜I sÕ+ð	,ð  $Ÿ|™|›~×-ˆä×ÑÐPÐRYÔZØ"Ö;�a¤j°´EÕ&:’Ò;Ð;ð .úò <ùs0   ‚ACÁ6CÂCÂ	CÂ'CÂ=CÃCÃCc              ‹   ó€  K  — t        |«      dk(  ryddlm} | j                  «       }t	        j                  «       }t        d|› �«       	 |j                  d¬«      4 ƒd{  –—† }| j                  ||«      ƒ d{  –—† }ddd«      ƒd{  –—†  t	        j                  «       }||z
  }	t        j                  | j                  j                  t        j                  |	dt        «       › �||t        |«      ¬«      «       S 7 ŒŸ7 Œ‡7 Œy# 1 ƒd{  –—†7  sw Y   Œ‰xY w# t         $ r–}
t	        j                  «       }||z
  }	t        j                  | j                  j#                  t        j                  |	|
dt        «       › �||t        |«      ¬	«      «       t%        j&                  d
t)        |
«      «       |
‚d}
~
ww xY w­w)a  
        Use Redis Pipelines for bulk increment operations
        Args:
            increment_list: List of RedisPipelineIncrementOperation dicts containing:
                - key: str
                - increment_value: float
                - ttl_seconds: int
        r   Nr8  z6Increment Async Redis Cache Pipeline: increment list: FrN  zasync_increment_pipeline <- rP  rQ  zOLiteLLM Redis Caching: async increment_pipeline() - Got exception from REDIS %s)r  rA  r   rä   rG   r   rR  r²  ri   r²   r™   r  r   rÀ   r3   r   r,   r¿   r   r®   r³   )rA   r­  rƒ   r   r  rÃ   rC  rK  rÄ   rþ   r|   s              r2   Úasync_increment_pipelinez#RedisCache.async_increment_pipelineª  s¸  è ø€ ô ˆ~Ó !Ò#Øå'à&*×&<Ñ&<Ó&>ˆÜ ŸI™I›Kˆ
äÐNÈ~ÐN^Ð_Ô`ð%	Ø$×-Ñ-¸%Ð-Ó@÷ ]ð ]ÀDØ'+×'FÑ'FÀtÈ^Ó'\×!\�÷]÷ ]ô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø <Ô=QÓ=SÐ<TÐUØ)Ø%Ü%FÀvÓ%Nð Có ô	ð ˆNð!]øØ!\øð]ø÷ ]÷ ]ñ ]ûô" ò 	ä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ <Ô=QÓ=SÐ<TÐUØ)Ø%Ü%FÀvÓ%Nð Có ô
ô × Ñ ØaÜ�A“ôð ˆGûð'	üs†   ‚AF>ÁD Á!DÁ"D Á%DÁ;DÁ<DÂ D ÂDÂA4D Ä F>ÄD ÄDÄD ÄDÄDÄDÄD Ä	F;Ä%BF6Æ6F;Æ;F>c              ƒ   ó  K  — 	 | j                  «       }| j                  |¬«      }|j                  |«      ƒ d{  –—† }|dk  ry|S 7 Œ# t        $ r6}t	        j
                  d|«       t        | j                  |«       Y d}~yd}~ww xY w­w)a  
        Get the remaining TTL of a key in Redis

        Args:
            key (str): The key to get TTL for

        Returns:
            Optional[int]: The remaining TTL in seconds, or None if key doesn't exist

        Redis ref: https://redis.io/docs/latest/commands/ttl/
        rÚ   Nr  zRedis TTL Error: %s)rä   ré   rý   r,   r   r´   rv   r†   )rA   rÛ   r  rý   r|   s        r2   Úasync_get_ttlzRedisCache.async_get_ttlè  sˆ   è ø€ ð	à(,×(>Ñ(>Ó(@ˆMØ×.Ñ.°3Ð.Ó7ˆCØ,×0Ñ0°Ó5×5ˆCØ�bŠyØØˆJð 6ùô ò 	Ü× Ñ Ð!6¸Ô:Ü+¨D×,AÑ,AÀ1ÔEÜûð	üsJ   ‚B„6A	 ºA»	A	 ÁBÁA	 ÁBÁA	 Á		BÁ,BÁ>BÂBÂBÚvaluesc              ‹   ó–  K  — | j                  «       }| j                  |¬«      }t        j                  «       }	  |j                  |g|¢­Ž ƒ d{  –—† }t        j                  «       }||z
  }	t	        j
                  | j                  j                  t        j                  |	dt        «       › �¬«      «       |S 7 Œi# t        $ r�}
t        j                  «       }||z
  }	t	        j
                  | j                  j                  t        j                  |	|
dt        «       › �¬«      «       t        j                  d|
«       |
‚d}
~
ww xY w­w)aR  
        Append one or multiple values to a list stored at key

        Args:
            key: The Redis key of the list
            values: One or more values to append to the list
            parent_otel_span: Optional parent OpenTelemetry span

        Returns:
            int: The length of the list after the push operation
        rÚ   Nzasync_rpush <- rŽ  rº   z:LiteLLM Redis Cache RPUSH: - Got exception from REDIS : %s)rä   ré   rG   Úrpushri   r²   r™   r  r   rÀ   r3   r,   r¿   r   r®   )rA   rÛ   r·  r:  rƒ   r  rÃ   r…  rÄ   rþ   r|   s              r2   Úasync_rpushzRedisCache.async_rpush  s?  è ø€ ð& %)×$:Ñ$:Ó$<ˆØ×*Ñ*¨sÐ*Ó3ˆÜ ŸI™I›Kˆ
ð	Ø$7 M×$7Ñ$7¸Ð$E¸fÒ$E×EˆHä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø /Ô0DÓ0FÐ/GÐHð Có ôð ˆOð Fùô ò 	ô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ /Ô0DÓ0FÐ/GÐHð	 Có ôô × Ñ Ð!]Ð_`ÔaØˆGûð	üs<   ‚7E	ºB< ÁB:ÁA(B< Â9E	Â:B< Â<	EÃA<EÅEÅE	Ú
rpush_listc              ƒ   óØ   K  — |D ]-  }| j                  |d   ¬«      } |j                  |g|d   ¢­Ž  Œ/ |j                  «       ƒ d{  –—† }|D ]  }t        |t        «      sŒ|‚ |S 7 Œ­w)z-Helper function for pipeline rpush operationsrÛ   rÚ   r·  N)ré   r¹  r  ro   r,   )rA   rC  r»  Úrpush_oprÛ   rK  r±  s          r2   Ú_pipeline_rpush_helperz!RedisCache._pipeline_rpush_helper5  s€   è ø€ ð #ò 	1ˆHØ×.Ñ.°8¸E±?Ð.ÓCˆCØˆD�J‰J�sÐ0˜X hÑ/Ô0ð	1ð  $Ÿ|™|›~×-ˆàò 	ˆAÜ˜!œYÕ'Ø�ð	ð ˆð .ús   ‚AA*ÁA(Á	A*Á#A*c              ƒ   ó*  K  — t        |«      dk(  rg S | j                  «       }t        j                  «       }	 |j                  d¬«      4 ƒd{  –—† }| j	                  ||«      ƒ d{  –—† }ddd«      ƒd{  –—†  t        j                  «       }||z
  }t        j                  | j                  j                  t        j                  |dt        «       › �¬«      «       S 7 Œ“7 Œ{7 Œm# 1 ƒd{  –—†7  sw Y   Œ}xY w# t        $ rŠ}t        j                  «       }||z
  }t        j                  | j                  j                  t        j                  ||dt        «       › �¬«      «       t        j                  dt!        |«      «       |‚d}~ww xY w­w)	a!  
        Use Redis Pipelines for bulk RPUSH operations

        Args:
            rpush_list: List of RedisPipelineRpushOperation dicts containing:
                - key: str
                - values: List[Any]

        Returns:
            List[int]: List lengths after each push
        r   FrN  Nzasync_rpush_pipeline <- rŽ  rº   zKLiteLLM Redis Caching: async_rpush_pipeline() - Got exception from REDIS %s)r  rä   rG   rR  r¾  ri   r²   r™   r  r   rÀ   r3   r,   r¿   r   r®   r³   )	rA   r»  r  rÃ   rC  rK  rÄ   rþ   r|   s	            r2   Úasync_rpush_pipelinezRedisCache.async_rpush_pipelineE  s‰  è ø€ ô  ˆz‹?˜aÒØˆIà$(×$:Ñ$:Ó$<ˆÜ ŸI™I›Kˆ
ð	Ø$×-Ñ-¸%Ð-Ó@÷ Uð UÀDØ'+×'BÑ'BÀ4ÈÓ'T×!T�÷U÷ Uô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø 8Ô9MÓ9OÐ8PÐQð Có ôð ˆNðUøØ!TøðUø÷ U÷ Uñ Uûô ò 	ä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ 8Ô9MÓ9OÐ8PÐQð	 Có ôô × Ñ Ø]Ü�A“ôð ˆGûð!	üó„   ‚5F¸C= ÁC"ÁC= ÁC(Á(C$Á)C(Á-C= Á8C&Á9A(C= Ã!FÃ"C= Ã$C(Ã&C= Ã(C:Ã.C1Ã/C:Ã6C= Ã=	FÄBFÆFÆFc              ƒ   ó¾   K  — g }t        |«      D ]F  }|j                  |«       |j                  «       ƒ d {  –—† }|D ]  }|€Œ|j                  |«       Œ ŒH |S 7 Œ#­wr�   )r'   Úlpopr  r*   )rA   rC  rÛ   r  r{   r0   rK  r±  s           r2   Ú*handle_lpop_count_for_older_redis_versionsz5RedisCache.handle_lpop_count_for_older_redis_versions|  se   è ø€ Ø%'ˆÜ�u“ò 	%ˆAØ�I‰I�cŒNØ ŸL™L›N×*ˆGð ò %�Ø‘=Ø—M‘M !Õ$ñ%ð	%ð ˆð +ús   ‚5A·A¸AÁAc              ‹   óÀ  K  — | j                  «       }| j                  |¬«      }t        j                  «       }t        d|› d|› �«       	 | j	                  «       }|�L|dk  rG|j                  d¬«      4 ƒd {  –—† }| j                  |||«      ƒ d {  –—† }	d d d «      ƒd {  –—†  n|j                  ||«      ƒ d {  –—† }	t        j                  «       }
|
|z
  }t        j                  | j                  j                  t        j                  |dt        «       › �¬«      «       t        	t         «      r	 |	j#                  d	«      S t        |	t&        «      r2t)        d
„ |	D «       «      r 	 |	D �cg c]  }|j#                  d	«      ‘Œ c}S |	S 7 �Œ7 Œû7 Œí# 1 ƒd {  –—†7  sw Y   ŒâxY w7 Œé# t$        $ r |	cY S w xY wc c}w # t$        $ r |	cY S w xY w# t$        $ r�}t        j                  «       }
|
|z
  }t        j                  | j                  j+                  t        j                  ||dt        «       › �¬«      «       t-        j.                  d|«       |‚d }~ww xY w­w)NrÚ   zLPOP from Redis list: key: z	, count: é   FrN  zasync_lpop <- rŽ  ri  c              3   ó<   K  — | ]  }t        |t        «      –— Œ y ­wr�   )ro   r   )r)  Úitems     r2   r*  z(RedisCache.async_lpop.<locals>.<genexpr>±  s   è ø€ Ò1]Èd´*¸TÄ5×2IÑ1]ùs   ‚rº   z9LiteLLM Redis Cache LPOP: - Got exception from REDIS : %s)rä   ré   rG   r   ró   rR  rÄ  rÃ  ri   r²   r™   r  r   rÀ   r3   ro   r   rc  r,   ÚlistÚallr¿   r   r®   )rA   rÛ   r  r:  rƒ   r  rÃ   rò   rC  r{   rÄ   rþ   rÈ  r|   s                 r2   Ú
async_lpopzRedisCache.async_lpop‰  se  è ø€ ð %)×$:Ñ$:Ó$<ˆØ×*Ñ*¨sÐ*Ó3ˆÜ ŸI™I›Kˆ
ÜÐ3°C°5¸	À%ÀÐIÔJð0	Ø#'×#BÑ#BÓ#DˆMàÐ  ]°QÒ%6à(×1Ñ1¸eÐ1ÓD÷ eð eÈØ#'×#RÑ#RÐSWÐY\Ð^cÓ#d×d�F÷e÷ eð eð  -×1Ñ1°#°uÓ=×=�ô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø .Ô/CÓ/EÐ.FÐGð Có ôô ˜&¤%Ô(ð"Ø!Ÿ=™=¨Ó1Ð1ô ˜F¤DÔ)¬cÑ1]ÐV\Ô1]Ô.]ð"Ø=CÖD°T˜DŸK™K¨Õ0ÒDÐDð ˆMð9eùØdøðeø÷ e÷ eñ eúð >ùô" !ò "Ø!’Mð"üò EøÜ ò "Ø!’Mð"ûô ò 	ô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ .Ô/CÓ/EÐ.FÐGð	 Có ôô × Ñ Ð!\Ð^_Ô`ØˆGûð	üs  ‚AIÁ-G Á8FÁ9G Á<FÂFÂFÂG Â#FÂ$G Â>F(Â?A7G Ä7F* ÅIÅ"G Å+G  Å/F;ÆG  Æ	IÆ
G ÆIÆG ÆFÆG ÆF%ÆFÆF%Æ!G Æ*F8Æ5G Æ6IÆ7F8Æ8G Æ;G  Ç GÇG ÇIÇGÇG Ç	IÇA<IÉIÉIÚ	lpop_listc           
   ƒ   óÆ  K  — | j                  «       }|dk\  rJ|D ],  }| j                  |d   ¬«      }|j                  ||d   «       Œ. |j                  «       ƒ d{  –—† }n®g }|D ]R  }| j                  |d   ¬«      }|d   xs d}|j	                  |«       t        |«      D ]  }	|j                  |«       Œ ŒT |j                  «       ƒ d{  –—† }
g }d}|D ]4  }|
|||z    D �cg c]  }|€Œ|‘Œ	 }}|j	                  |r|nd«       ||z  }Œ6 |D ]  }t        |t        «      sŒ|‚ g }|D ]€  }|€|j	                  d«       Œt        |t        «      rI	 |j	                  |D �cg c](  }|€Œt        |t        «      r|j                  d«      n|‘Œ* c}xs d«       Œp|j	                  d«       Œ‚ |S 7 �ŒV7 Œæc c}w c c}w # t        $ r |j	                  |«       Y Œ°w xY w­w)	zÍHelper function for pipeline lpop operations.

        For Redis >= 7, queues one LPOP(key, count) per operation.
        For Redis < 7, queues `count` individual LPOP(key) commands per operation.
        rÆ  rÛ   rÚ   r  Nr   r   ri  )ró   ré   rÃ  r  r*   r'   ro   r,   rÉ  r   rc  )rA   rC  rÌ  rò   Úlpop_oprÛ   Úraw_resultsÚcountsr  r0   Úflat_resultsÚoffsetr±  Úkey_resultsr€  rÈ  s                   r2   Ú_pipeline_lpop_helperz RedisCache._pipeline_lpop_helperÇ  s  è ø€ ð  $×>Ñ>Ó@ˆà˜AÒØ$ò 1�Ø×2Ñ2°w¸u±~Ð2ÓF�Ø—	‘	˜#˜w wÑ/Õ0ð1ð !%§¡£×.‰Kð (*ˆFØ$ò #�Ø×2Ñ2°w¸u±~Ð2ÓF�Ø Ñ(Ò-¨A�Ø—‘˜eÔ$Ü˜u›ò #�AØ—I‘I˜c•Nñ#ð	#ð )-¯©«×"6ˆLð ˆKØˆFØò  �Ø*6°vÀÈÁÐ*OÖa QÐSTÑS`šqÐa�ÐaØ×"Ñ"±+¡;À4ÔHØ˜%‘‘ð ð ò 	ˆAÜ˜!œYÕ'Ø�ð	ð
 :<ˆØò 	-ˆAØˆyØ×&Ñ& tÕ,Ü˜AœtÔ$ð.Ø#×*Ñ*Ø_`ÖuÐW[ÐdhÑdt´¸DÄ%Ô1H˜Ÿ™ WÔ-ÈdÑRÒuò  Øõð  ×&Ñ& tÕ,ð	-ð ÐðS /ùð #7úò bùò" vøô !ò .Ø#×*Ñ*¨1Ö-ð.üs   ‚AG!ÁF2ÁA1G!ÃF5ÃG!Ã&F7Ã.F7Ã23G!Ä&.G!ÅGÅ$F<
Å,%F<
ÆGÆG!Æ5G!Æ7G!Æ<GÇGÇG!ÇGÇG!c              ƒ   ó*  K  — t        |«      dk(  rg S | j                  «       }t        j                  «       }	 |j                  d¬«      4 ƒd{  –—† }| j	                  ||«      ƒ d{  –—† }ddd«      ƒd{  –—†  t        j                  «       }||z
  }t        j                  | j                  j                  t        j                  |dt        «       › �¬«      «       S 7 Œ“7 Œ{7 Œm# 1 ƒd{  –—†7  sw Y   Œ}xY w# t        $ rŠ}t        j                  «       }||z
  }t        j                  | j                  j                  t        j                  ||dt        «       › �¬«      «       t        j                  dt!        |«      «       |‚d}~ww xY w­w)	aC  
        Use Redis Pipelines for bulk LPOP operations

        Args:
            lpop_list: List of RedisPipelineLpopOperation dicts containing:
                - key: str
                - count: Optional[int]

        Returns:
            List[Optional[List[str]]]: Decoded results per key, None if key was empty
        r   FrN  Nzasync_lpop_pipeline <- rŽ  rº   zJLiteLLM Redis Caching: async_lpop_pipeline() - Got exception from REDIS %s)r  rä   rG   rR  rÔ  ri   r²   r™   r  r   rÀ   r3   r,   r¿   r   r®   r³   )	rA   rÌ  r  rÃ   rC  rK  rÄ   rþ   r|   s	            r2   Úasync_lpop_pipelinezRedisCache.async_lpop_pipeline  s‰  è ø€ ô  ˆy‹>˜QÒØˆIà$(×$:Ñ$:Ó$<ˆÜ ŸI™I›Kˆ
ð	Ø$×-Ñ-¸%Ð-Ó@÷ Sð SÀDØ'+×'AÑ'AÀ$È	Ó'R×!R�÷S÷ Sô —y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&Ø 7Ô8LÓ8NÐ7OÐPð Có ôð ˆNðSøØ!RøðSø÷ S÷ Sñ Sûô ò 	ä—y‘y“{ˆHØ  :Ñ-ˆIÜ×ÑØ×'Ñ'×BÑBÜ(×.Ñ.Ø&ØØ 7Ô8LÓ8NÐ7OÐPð	 Có ôô × Ñ Ø\Ü�A“ôð ˆGûð!	ürÁ  )NNNrš   NNg      @r�   )rš   )NNF)NN)MrP   rQ   rR   rT   r³   rÉ  rî   rB   r¨   r,   rµ   r·   rÖ   rß   rà   rä   ré   ró   rá   r	  rŠ   r  r   r   r	   r!  r  rB  rR  Úcluster_pipeliner   r-  r  rL  rS  rV  rX  r[  r   rU   r`  re  rZ  rm  rÞ   r   ru  rw  r{  rƒ  r†  rˆ  rŒ  r°   r“  r•  rN   rš  r™  rŸ  r¨  rª  r¬  r   r²  r´  r¶  rº  r   r¾  rÀ  rÄ  rË  r   rÔ  rÖ  Ú__classcell__)r¬   s   @r2   rŒ   rŒ     sÑ  ø„ ð
 ØØØ'*Ø $Ø%)Ø'*ñCð
  ™*ðCð ˜‘:ðCð ˜d‘{ðCð  ™õCòJ,ð0¨)ó ð"¨ó ð"	3¨Só 	3ð"à	Ð8Ñ	8ó"ð(	¨3ð 	°3ó 	ð/¨Có /ò:^ñ(6¨#ð 6°E¸D±Lð 6ÐVYó 6ðp "ñ-¨Sð -¸ð -Àtò -ó "ð-ð^3¨Cð 3°H¸SÀ)ÈCÁ.Ð=PÑ4Qó 3ðj"R¸ð "RÀÈÈiÐX[ÉnÐI\Ñ@]ó "RðH "ñTFó "ðTFðlàÐ)Ñ)ðð ˜U 3¨ ;Ñ/Ñ0ðð �T‰\ð	ð
 
óð8 "àLPñ8FØ" 5¨¨f¨Ñ#5Ñ6ð8FØ=BÀT¹\ò8Fó "ð8Fðtà(ðð ðð ð	ð
 �T‰\ðð 
óð" "ðAF°Tð AFÀÈÁò AFó "ðAFðF "ñ,ó "ð,ð "ð
 Ø(,Ø!ñ;ð ð;ð �4‰Zð	;ð
  ™+ð;ð ð;ð 
ò;ó "ð;ðz "ð
 ñ	"àð"ð ð"ð �4‰Zð	"ð
 
�‰ò"ó "ð"òH-ð
°ó ñc¨t°d©{ó cð,1¨d°3©ið 1¸HÀUÈSÁ[ÐSWÑEWÑ<Xó 1ð8¸$¸s¹)ð 8ÈÐQVÐY\ÑQ\Ð_cÑQcÑHdó 8ð )-ñ2"à�s‘)˜d 3¨¡:Ñ.Ñ.ð2"ð  ™+ð2"ð 
ó	2"ðh "ñ+F¸4À$¹;ò +Fó "ð+FðZ "ð )-ñF"à�s‘)˜d 3¨¡:Ñ.Ñ.ðF"ð  ™+ðF"ð 
ò	F"ó "ðF"ðP ˜4ó  ðD ˜Dó  ðD "ñ*ó "ð*ð˜Tó òò%ò%òKð# tó #ðJ "ð/¨Cò /ó "ð/ò&ð<àð<ð Ð<Ñ=ð<ð 
ˆe‰�tÑ	ó	<ð, "ð;Ø"Ð#BÑCð;à	ˆe‰�tÑ	ò;ó "ð;ðz "ð sð ¨s°T©zò ó "ðð2 "ð
 )-ñ	0àð0ð ˜˜u™ sÑ*¨UÑ2Ñ3ð0ð  ™+ð	0ð 
ò0ó "ð0ðdàðð Ð8Ñ9ðð 
ˆc‰ó	ð  "ð4àÐ8Ñ9ð4ð 
ˆc‰ò4ó "ð4ðlÀXð ÐTWð Ð`cð ÐhlÐmrÑhsó ð "ð !Ø(,ñ	;àð;ð �T‰zð;ð  ™+ð	;ð 
ˆt�C‰y‰ò;ó "ð;ðz9àð9ð Ð2Ñ3ð9ð 
ˆd�3‰i˜$ÑÑ	ó	9ðv "ð4àÐ2Ñ3ð4ð 
ˆd�3‰i˜$ÑÑ	ò4ó "ô4rC   rŒ   )r“   )MrS   rk  ri   rˆ   rÏ   r$   rÍ   rG   Úcollections.abcr   r   r   Úcontextvarsr   Údatetimer   Útypingr   r	   r
   r   r   r©   Úlitellm._loggingr   r   Úlitellm.constantsr   r   r   r   Ú'litellm.litellm_core_utils.core_helpersr   Ú,litellm.litellm_core_utils.coroutine_checkerr   Úlitellm.types.cachingr   r   r   Úlitellm.types.servicesr   Ú
base_cacher   Úopentelemetry.tracer   Ú_SpanrA  r   r   Úredis.asyncio.clientr   Úredis.asyncio.clusterr   rR  r×  rß   rà   rT   r³   r3   r5   rW   rZ   Ú__annotations__r  r`   Ú	lru_cacher-  r^   rl   ÚBaseExceptionrU   rq   rv   r}   rŠ   rŒ   rV   rC   r2   ú<module>rë     s¹  ðòó Û Û Û Û Û Û ß 9Ñ 9Ý "Ý ß ;Õ ;ã ß :÷ó õ VÝ J÷ñ õ
 0å !áÝ1ß1Ý-Ý5à€HØ&ÐØÐØ!-ÐØ�Dà€HØÐØÐØ!$ÐØ€Dñ$ Sð $°ó $÷NE"ñ E"ñP Ð-Ó.Ð ñ 5?Ð?aÐklÔ4mÐ ˜5 ¨C¡Ñ1Ó mð1˜Vð 1¨ó 1ð €×Ñ˜QÔðx 5¨¨s¨Ñ#3ò xó  ðxð$ -ð °Dó ðGÐ-@ð GÀ}ð GÐY]ó GðØ ðà
ðð �2�yÐ!1Ñ2Ð2Ñ
3ðð ó	ò2ô,h�õ hrC   