
    @=j                         d Z ddlZddlZddlZddlmZ da ej                    ZdZ	ddddd	e
d
edededef
dZdedefdZdedz  dedz  dedefdZddd	e
dedz  dedz  dedede
deeedz  f         fdZdS )u   Retry utilities — jittered backoff for decorrelated retries.

Replaces fixed exponential backoff with jittered delays to prevent
thundering-herd retry spikes when multiple sessions hit the same
rate-limited provider concurrently.
    N)Any)g      >@g      N@g     V@      ^@g      @r   g      ?
base_delay	max_delayjitter_ratioattemptr   r   r   returnc                n   t           5  t          dz  at          }ddd           n# 1 swxY w Y   t          d| dz
            }|dk    s|dk    r|}nt          |d|z  z  |          }t	          j                    |dz  z  dz  }t          j        |          }|                    d||z            }	||	z   S )aC  Compute a jittered exponential backoff delay.

    Args:
        attempt: 1-based retry attempt number.
        base_delay: Base delay in seconds for attempt 1.
        max_delay: Maximum delay cap in seconds.
        jitter_ratio: Fraction of computed delay to use as random jitter
            range.  0.5 means jitter is uniform in [0, 0.5 * delay].

    Returns:
        Delay in seconds: min(base * 2^(attempt-1), max_delay) + jitter.

    The jitter decorrelates concurrent retries so multiple sessions
    hitting the same provider don't all retry at the same instant.
       Nr   ?      l   yn< l    )	_jitter_lock_jitter_countermaxmintimetime_nsrandomRandomuniform)
r	   r   r   r   tickexponentdelayseedrngjitters
             7/home/rurouni/.hermes/hermes-agent/agent/retry_utils.pyjittered_backoffr      s    . 
  1               1gk""H2~~qJ!x-0)<< LNNdZ/0J>D
-

C[[L5011F6>s   &**errorc                     | t          | dd          t          | dd          t          | dd          g}d                    d |D                                                       S )zCBest-effort flattened provider error text for retry classification.messageNbodyresponse c              3   8   K   | ]}|t          |          V  d S )N)str).0parts     r   	<genexpr>z_error_text.<locals>.<genexpr>M   s-      DD$43CCII3C3C3C3CDD    )getattrjoinlower)r    partss     r   _error_textr0   E   sj     	y$''vt$$z4((	E 88DD%DDDDDJJLLLr+   base_urlmodelc                     | pd                                 }|pd                                 }t          |dd          }t          |          }|dk    od|v od|v od|v pd|v S )	aL  Return True for Z.AI Coding Plan transient overload 429s.

    The coding-plan endpoint reports overload as HTTP 429 with body code 1305
    and message "The service may be temporarily overloaded...". Treat only
    that narrow shape specially so ordinary quota/billing 429s still fail fast
    through the existing classifier.
     status_codeNi  zapi.z.ai/api/coding/paas/v4zglm-5.21305ztemporarily overloaded)r.   r,   r0   )r1   r2   r    base
model_namestatustexts          r   is_zai_coding_overload_errorr;   P   s     N!!##D+2$$&&JUM400FuD# 	A)T1	A#	A t^?74?	r+      )short_attemptsdefault_waitr=   c                    t          |||          s|dfS | |k    r|dfS t          | |z
  dz
  t          t                    dz
            }t          |         }t	          d||d          dfS )u7  Provider-aware rate-limit backoff.

    For most providers this returns ``default_wait`` unchanged. For Z.AI
    Coding Plan GLM-5.2 overloads, keep the first ``short_attempts`` retries on
    the normal short exponential schedule, then switch to progressively longer
    waits (30s → 60s → 90s → 120s, capped) plus light jitter.

    ``attempt`` is 1-based, matching the retry loop's logged attempt number.
    Returns ``(wait_seconds, reason_label)`` where ``reason_label`` is suitable
    for status/log decoration when a provider-specific policy fired.
    )r1   r2   r    Nzai_coding_overload_shortr   g?r   zai_coding_overload_long)r;   r   len!_ZAI_CODING_OVERLOAD_LONG_BACKOFFr   )r	   r1   r2   r    r>   r=   idxr   s           r   adaptive_rate_limit_backoffrE   d   s    ( (eTTT "T!!.  888
g&*C0Q,R,RUV,V
W
WC237J A*
Y\]]]_yyyr+   )__doc__r   	threadingr   typingr   r   Lockr   rC   intfloatr   r'   r0   boolr;   tuplerE    r+   r   <module>rO      s               
 y~ %> ! & & && & 	&
 & & & & &RMs Ms M M M McDj t TW \`    6 z z zz Djz :	z
 z z z 5#*z z z z z zr+   