
    )jt                       d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	m
Z
mZ  ej        e          Z G d dej                  Ze G d d	                      Zg d
Zg dZg dZg dZg dZg dZg dZg dZg dZg dZg dZg dZg dZdgZg dZ  e!h d          Z"g dZ#g dZ$ddddddd<d)Z%dd*d=d1Z&d>d2Z'dd*d?d3Z(d@d4Z)dAd6Z*dBd8Z+dCd9Z,dDd:Z-dEd;Z.dS )Fa  API error classification for smart failover and recovery.

Provides a structured taxonomy of API errors and a priority-ordered
classification pipeline that determines the correct recovery action
(retry, rotate credential, fallback to another provider, compress
context, or abort).

Replaces scattered inline string-matching with a centralized classifier
that the main retry loop in run_agent.py consults for every API failure.
    )annotationsN)	dataclassfield)AnyDictOptionalc                  f    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdZdZdZdS )FailoverReasonu8   Why an API call failed — determines recovery strategy.authauth_permanentbilling
rate_limit
overloadedserver_errortimeoutcontext_overflowpayload_too_largeimage_too_largemodel_not_foundprovider_policy_blockedcontent_policy_blockedformat_errorinvalid_encrypted_content#multimodal_tool_content_unsupportedthinking_signaturelong_context_tier!oauth_long_context_beta_forbiddenllama_cpp_grammar_patternunknownN)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r        ;/home/ubuntu/.hermes/hermes-agent/agent/error_classifier.pyr
   r
      s        BB D%N GJ J!L G *+'O (O75 "L ;*O' .+(K% ; GGGr%   r
   c                      e Zd ZU dZded<   dZded<   dZded<   dZded	<   d
Zded<    e	e
          Zded<   dZded<   dZded<   dZded<   dZded<   edd            ZdS )ClassifiedErrorz>Structured classification of an API error with recovery hints.r
   reasonNOptional[int]status_codezOptional[str]providermodel strmessage)default_factoryzDict[str, Any]error_contextTbool	retryableFshould_compressshould_rotate_credentialshould_fallbackreturnc                @    | j         t          j        t          j        hv S N)r)   r
   r   r   )selfs    r&   is_authzClassifiedError.is_authW   s    {~2N4QRRRr%   )r8   r3   )r    r!   r"   r#   __annotations__r+   r,   r-   r0   r   dictr2   r4   r5   r6   r7   propertyr<   r$   r%   r&   r(   r(   E   s         HH!%K%%%%"H""""EG$)E$$?$?$?M???? I!O!!!!%*****!O!!!!S S S XS S Sr%   r(   )zinsufficient creditsinsufficient_quotazinsufficient balancezcredit balancezcredits exhaustedzcredits have been exhaustedzno usable creditsztop up your creditszpayment requiredzbilling hard limitzexceeded your current quotazaccount is deactivatedzplan does not includezout of fundszrun out of fundsbalance_depleted model_not_supported_on_free_tierznot available on the free tier)z
rate limitr   ztoo many requests	throttledzrequests per minuteztokens per minutezrequests per dayztry again inzplease retry afterresource_exhaustedzrate increased too quicklythrottlingexceptionztoo many concurrent requestsservicequotaexceededexception)zusage limitquotazlimit exceededkey limit exceeded)z	try againretryz	resets atzreset inwaitzrequests remainingperiodicwindow)zrequest entity too largezpayload too largezerror code: 413)zimage exceedszimage too larger   zimage size exceedszimage dimensions exceedz"dimensions exceed max allowed sizezmax allowed size: 8000)ztext is not setz%tool message content must be a stringztool content must be a stringztool message must be a stringzexpected string, got listzexpected string, got arrayz tool_call.content must be string)zcontext lengthzcontext sizezmaximum contextztoken limitztoo many tokenszreduce the lengthzexceeds the limitzcontext windowzprompt is too longzprompt exceeds max length
max_tokenszmaximum number of tokenszexceeds the max_model_lenmax_model_lenzprompt lengthinput is too longzmaximum model lengthzcontext length exceededztruncating inputzslot context
n_ctx_slotu   超过最大长度u   上下文长度rO   zmax input tokenzinput tokenz*exceeds the maximum number of input tokens)zis not a valid modelzinvalid modelzmodel not foundr   zdoes not existzno such modelzunknown modelzunsupported model)zunknown parameterzunsupported parameterzunrecognized request argumentinvalid_request_errorunknown_parameterunsupported_parameter)z.no endpoints available matching your guardrailz0no endpoints available matching your data policyz,no endpoints found matching your data policy)	z'flagged for possible cybersecurity riskztrusted access for cyberzviolates our usage policiesz violates openai's usage policieszyour request was flagged byz prompt was flagged by our safetyz+responses cannot be generated due to safetycontent_filterresponsibleaipolicyviolation)	zinvalid api keyinvalid_api_keyauthenticationunauthorized	forbiddenzinvalid tokenztoken expiredztoken revokedzaccess denied	signature)z	timed outzturn timed outzrequest timed outzdeadline exceededzoperation timed outzupstream timed out>   SSLError	ReadErrorPoolTimeoutReadTimeoutSSLEOFErrorConnectErrorTimeoutErrorConnectTimeoutAPITimeoutErrorBrokenPipeErrorConnectionErrorSSLSyscallErrorSSLWantReadErrorSSLWantWriteErrorAPIConnectionErrorSSLZeroReturnErrorRemoteProtocolErrorConnectionResetErrorConnectionAbortedErrorServerDisconnectedError)zserver disconnectedzpeer closed connectionzconnection reset by peerzconnection was closedznetwork connection lostzunexpected eofzincomplete chunked read)zbad record macz	ssl alertz	tls alertzssl handshake failureztlsv1 alertzsslv3 alertbad_record_mac	ssl_alert	tls_alerttls_alert_internal_errorz[ssl:r.   i@ )r,   r-   approx_tokenscontext_lengthnum_messageserror	Exceptionr,   r/   r-   rs   intrt   ru   r8   c               p
    t                     t                     j        }|dk    rdt                     t	                    }t                                                     }d}	d}
t          t                    r	                    di           }t          |t                    rIt          |	                    d          pd                                          }	|	                    di           }t          |t                    r|	                    d          pd}t          |t
                    r|
                                r	 d	dl}|                    |          }t          |t                    ra|	                    di           }t          |t                    r6t          |	                    d          pd                                          }
n# |j        t          f$ r Y nw xY w|	s6t          	                    d          pd                                          }	|g}|	r|	|vr|                    |	           |
r|
|vr|
|	vr|                    |
           d
                    |          pd
                                                                }pd
                                                                }d. fd}t#          fdt$          D                       r |t&          j        dd          S dk    r(dv r$dv sdv sdv r |t&          j        dd          S dk    r dv rdv r |t&          j        dd          S dk    r dv rdv r |t&          j        dd          S dk    r(dv sdv sd v rd!v r |t&          j        dd          S d"v sd#v rd$v r |t&          j        dd          S t5          |||||||%
  
        }||S |rt7          ||          }||S t9          ||||&          }||S t#          fd't:          D                       r |t&          j        d(          S t#          fd)t>          D                       }|rNsL||d*z  k    p|d+k    o|d,k    p|d-k    }|r |t&          j         dd          S  |t&          j        d(          S |tB          v s"t           tD          tF          tH          f          r |t&          j        d(          S  |t&          j%        d(          S )/u  Classify an API error into a structured recovery recommendation.

    Priority-ordered pipeline:
      1. Special-case provider-specific patterns (thinking sigs, tier gates)
      2. HTTP status code + message-aware refinement
      3. Error code classification (from body)
      4. Message pattern matching (billing vs rate_limit vs context vs auth)
      5. SSL/TLS transient alert patterns → retry as timeout
      6. Server disconnect + large session → context overflow
      7. Transport error heuristics
      8. Fallback: unknown (retryable with backoff)

    Args:
        error: The exception from the API call.
        provider: Current provider name (e.g. "openrouter", "anthropic").
        model: Current model slug.
        approx_tokens: Approximate token count of the current context.
        context_length: Maximum context length for the current model.

    Returns:
        ClassifiedError with reason and recovery action hints.
    NRateLimitError  r.   rv   r0   metadatarawr    r)   r
   r8   r(   c                r    | t                    d}|                    |           t          di |S )N)r)   r+   r,   r-   r0   r$   )_extract_messageupdater(   )r)   	overridesdefaultsbodyrv   r-   r,   r+   s      r&   _resultz#classify_api_error.<locals>._result  sP    & 't44
 
 		"""*****r%   c              3      K   | ]}|v V  	d S r:   r$   .0p	error_msgs     r&   	<genexpr>z%classify_api_error.<locals>.<genexpr>!  s'      
D
Da1	>
D
D
D
D
D
Dr%   FTr4   r7     thinkingrZ   zcannot be modifiedzmust remain as they werer4   r5   zextra usagezlong contextzlong context betaznot yet availablezerror parsing grammarzjson-schema-to-grammarzunable to generate parsertemplatez'do not have an active grok subscriptionzout of available resourcesgrokr,   r-   rs   rt   ru   	result_fn)rs   rt   r   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z%classify_api_error.<locals>.<genexpr>  s'      
;
;a1	>
;
;
;
;
;
;r%   r4   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z%classify_api_error.<locals>.<genexpr>  s'      LL1YLLLLLLr%   g333333?  i    )r)   r
   r8   r(   )&_extract_status_codetyper    _extract_error_body_extract_error_coder/   lower
isinstancer>   getstripjsonloadsJSONDecodeError	TypeErrorappendjoinany _CONTENT_POLICY_BLOCKED_PATTERNSr
   r   r   r   r   r   r   _classify_by_status_classify_by_error_code_classify_by_message_SSL_TRANSIENT_PATTERNSr   _SERVER_DISCONNECT_PATTERNSr   _TRANSPORT_ERROR_TYPESra   re   OSErrorr   )rv   r,   r-   rs   rt   ru   
error_type
error_code_raw_msg	_body_msg_metadata_msg_err_obj	_metadata	_raw_jsonr   _inner
_inner_errpartsprovider_lowermodel_lowerr   
classifiedis_disconnectis_larger   r   r+   s   ```                     @@@r&   classify_api_errorr     s   > 'u--Ke%J z-===u%%D$T**J 5zz!!HIM$ ?88GR((h%% 	HLL339r::@@BBI Z44I)T** %MM%006B	i-- 	)//2C2C 	#!%I!6!6%fd33 ])/GR)@)@J)*d;; ]03JNN94M4M4SQS0T0T0Z0Z0\0\ 0)<    	?DHHY//5266<<>>IJE  Yh..Y $h66=PY;Y;Y]###In"++--3355N;B%%''--//K	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+( 
D
D
D
D#C
D
D
DDD 
w1 
 
 
 	
2 	s)##9$$#y00)Y66 w-!
 
 
 	
 	sY&&i''w, 
 
 
 	
 	s9,,9,,w<!
 
 
 	
 	s#y00'944+y88)++ w4!
 
 
 	
4 	2Y>>(I55&I:M:Mw 
 
 
 	
 (J#;'%
 
 

 !  ,ZGLL
! &:#%	  J  
;
;
;
;#:
;
;
;;; ?w~->>>> LLLL0KLLLLLM ?[ ? !>C#77 
f$W-&*@*VLSVDV 	  	7/ $   
 w~->>>> +++z%,P_ahAi/j/j+w~->>>> 7>)T::::s   BG+ +G?>G?)ru   r+   r   r   r   r>   Optional[ClassifiedError]c                  | dk    r |	t           j        ddd          S | dk    rYdv s$dv s t          fdt          D                       r |	t           j        ddd          S  |	t           j        dd	          S | d
k    rt          |	          S | dk    rt          fdt          D                       r |	t           j        ddd          S t          fdt          D                       r |	t           j        dd	          S t          fdt          D                       r |	t           j	        dd	          S  |	t           j
        d          S | dk    r |	t           j        dd          S | dk    r |	t           j        ddd          S | dk    rt          ||||||||		  	        S | dv ret          fdt          D                       s|                                dv r |	t           j        dd	          S  |	t           j        d          S | dv r |	t           j        d          S d| cxk    rdk     rn n |	t           j        dd	          S d| cxk    rdk     rn n |	t           j        d          S dS )zAClassify based on HTTP status code with message-aware refinement.i  FTr4   r6   r7   i  rH   zspending limitc              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z&_classify_by_status.<locals>.<genexpr>  s'      ==a1	>======r%   r   i  i  c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z&_classify_by_status.<locals>.<genexpr>"  s'      99!qI~999999r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z&_classify_by_status.<locals>.<genexpr>.  s'      II!qI~IIIIIIr%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z&_classify_by_status.<locals>.<genexpr>4  s'      AA!qI~AAAAAAr%   r   i  r   r{   r   r   >       c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z&_classify_by_status.<locals>.<genexpr>i  s'      EE1YEEEEEEr%   >   rR   rQ   rS   >       r   X  N)r
   r   r   _BILLING_PATTERNSr   _classify_402!_PROVIDER_POLICY_BLOCKED_PATTERNSr   _MODEL_NOT_FOUND_PATTERNSr   r   r   r   _classify_400_REQUEST_VALIDATION_PATTERNSr   r   r   r   )
r+   r   r   r   r,   r-   rs   rt   ru   r   s
    `        r&   r   r     s    c y%) 	
 
 
 	
 c !I--9,,====+<===== - 9&)- $	    y 
 
 
 	
 cY	222c
 9999'899999 	9&)- $	    IIII'HIIIII 	96 %   
 AAAA'@AAAAA 	9. $    y"
 
 
 	

 cy, 
 
 
 	
 cy%%) 	
 
 
 	
 cz4U')%
 
 
 	
 j   EEEE(DEEEEE		!! &? ? ? 9+ $   
 y4EEEEj  y2dCCCC kCy' 
 
 
 	
 kCy4EEEE4r%   c                     t           fdt          D                       }t           fdt          D                       }|r|r |t          j        ddd          S  |t          j        ddd          S )u  Disambiguate 402: billing exhaustion vs transient usage limit.

    The key insight from OpenClaw: some 402s are transient rate limits
    disguised as payment errors.  "Usage limit, try again in 5 minutes"
    is NOT a billing problem — it's a periodic quota that resets.
    c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_402.<locals>.<genexpr>  '      HHQ!y.HHHHHHr%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_402.<locals>.<genexpr>  s'      VV!qI~VVVVVVr%   Tr   F)r   _USAGE_LIMIT_PATTERNS_USAGE_LIMIT_TRANSIENT_SIGNALSr
   r   r   )r   r   has_usage_limithas_transient_signals   `   r&   r   r     s     HHHH2GHHHHHOVVVV7UVVVVV 
/ 
y%%) 	
 
 
 	
 9!%	   r%   c                   t           fdt          D                       r |t          j        d          S t           fdt          D                       r |t          j        d          S |pd                                }	|	dk    sd v sd v rd v r |t          j        dd	
          S t           fdt          D                       s|	dv r |t          j	        d	d
          S t           fdt          D                       r |t          j        dd          S t           fdt          D                       r |t          j        d	d	
          S t           fdt          D                       r |t          j        d	d
          S t           fdt           D                       r |t          j        ddd          S t           fdt$          D                       r |t          j        d	dd          S d}
t)          |t*                    r|                    di           }t)          |t*                    rHt/          |                    d          pd                                                                          }
|
sHt/          |                    d          pd                                                                          }
t3          |
          dk     p|
dv }||dz  k    p|dk    o|dk    p|dk    }|r|r |t          j        dd          S  |t          j	        d	d
          S )uH   Classify 400 Bad Request — context overflow, format error, or generic.c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_400.<locals>.<genexpr>  '      
E
Ea1	>
E
E
E
E
E
Er%   Tr   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_400.<locals>.<genexpr>  '      
=
=a1	>
=
=
=
=
=
=r%   r.   r   zencrypted content for itemzcould not be verifiedFr   c              3  ,   K   | ]}|d k    |v V  dS )rQ   Nr$   r   s     r&   r   z _classify_400.<locals>.<genexpr>  s>       - -q+++ N++++- -r%   >   rR   rS   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_400.<locals>.<genexpr>  '      
>
>a1	>
>
>
>
>
>
>r%   r   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_400.<locals>.<genexpr>   r   r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_400.<locals>.<genexpr>  r   r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_400.<locals>.<genexpr>  '      
8
8a1	>
8
8
8
8
8
8r%   r   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z _classify_400.<locals>.<genexpr>  '      
5
5a1	>
5
5
5
5
5
5r%   rv   r0      >   r.   rv   g?r   i8 P   )r   !_MULTIMODAL_TOOL_CONTENT_PATTERNSr
   r   _IMAGE_TOO_LARGE_PATTERNSr   r   r   r   r   _CONTEXT_OVERFLOW_PATTERNSr   r   r   r   r   _RATE_LIMIT_PATTERNSr   r   r   r   r>   r   r/   r   len)r   r   r   r,   r-   rs   rt   ru   r   error_code_lowererr_body_msgerr_obj
is_genericr   s   `             r&   r   r     s[   * 
E
E
E
E#D
E
E
EEE 
y>
 
 
 	
 
=
=
=
=#<
=
=
=== 
y*
 
 
 	
 #(b//11777&)33(I55'944 y4!
 
 
 	
0 	 - - - -$@ - - - 	- 	-	
 MMMy' 
 
 
 	
 
>
>
>
>#=
>
>
>>> 
y+ 
 
 
 	
 
E
E
E
E#D
E
E
EEE 
y2!
 
 
 	

 
=
=
=
=#<
=
=
=== 
y* 
 
 
 	
 
8
8
8
8#7
8
8
888 
y%%) 	
 
 
 	
 
5
5
5
5#4
5
5
555 
y"%) 	
 
 
 	
 L$ J((7B''gt$$ 	Mw{{955;<<BBDDJJLLL 	Jtxx	228b99??AAGGIIL\""R'H<=+HJ ~33 & Qme&;&P|b?P   
h 
y+ 
 
 
 	
 9#   r%   c                L   |                                  }|dv r |t          j        dd          S |dv r |t          j        ddd          S |dv r |t          j        dd          S |d	v r |t          j        dd
          S |dk    r |t          j        dd          S dS )z:Classify by structured error codes from the response body.>   rC   rD   rate_limit_exceededT)r4   r6   >   rA   payment_requiredno_usable_creditsbilling_not_activer@   insufficient_creditsrB   Fr   >   invalid_modelr   model_not_availabler   >   max_tokens_exceededcontext_length_exceededr   r   N)r   r
   r   r   r   r   r   )r   r   r   
code_lowers       r&   r   r   A  s$    !!##JOOOy%%)
 
 
 	
     y"%) 	
 
 
 	
 PPPy* 
 
 
 	
 GGGy+ 
 
 
 	
 000y4!
 
 
 	
 4r%   r   c               T    t           fdt          D                       r |t          j        dd          S t           fdt          D                       r |t          j        d          S t           fdt          D                       r |t          j        d          S t           fdt          D                       }|rTt           fdt          D                       }|r |t          j
        ddd	          S  |t          j        d
dd	          S t           fdt          D                       r |t          j        d
dd	          S t           fdt          D                       r |t          j
        ddd	          S t           fdt          D                       r |t          j        dd          S t           fdt           D                       r |t          j        d
dd	          S t           fdt$          D                       r |t          j        d
d
          S t           fdt(          D                       r |t          j        d
d          S t           fdt,          D                       r |t          j        d          S dS )zJClassify based on error message patterns when no status code is available.c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  s'      
?
?a1	>
?
?
?
?
?
?r%   Tr   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   r   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  s'      "Z"Za1	>"Z"Z"Z"Z"Z"Zr%   r   Fc              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  s'      
2
2a1	>
2
2
2
2
2
2r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   r   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   c              3      K   | ]}|v V  	d S r:   r$   r   s     r&   r   z'_classify_by_message.<locals>.<genexpr>  r   r%   N)r   _PAYLOAD_TOO_LARGE_PATTERNSr
   r   r   r   r   r   r   r   r   r   r   r   r   r   _AUTH_PATTERNSr   r   r   r   r   _TIMEOUT_MESSAGE_PATTERNSr   )r   r   rs   rt   r   r   r   s   `      r&   r   r   x  s    
?
?
?
?#>
?
?
??? 
y, 
 
 
 	
 
E
E
E
E#D
E
E
EEE 
y>
 
 
 	
 
=
=
=
=#<
=
=
=== 
y*
 
 
 	
 HHHH2GHHHHHO 
""Z"Z"Z"Z;Y"Z"Z"ZZZ 	9))- $	    y"%) 	
 
 
 	
 
5
5
5
5#4
5
5
555 
y"%) 	
 
 
 	
 
8
8
8
8#7
8
8
888 
y%%) 	
 
 
 	
 
>
>
>
>#=
>
>
>>> 
y+ 
 
 
 	
 
2
2
2
2>
2
2
222 
y%) 	
 
 
 	
 
E
E
E
E#D
E
E
EEE 
y2!
 
 
 	
 
=
=
=
=#<
=
=
=== 
y* 
 
 
 	
 
=
=
=
=#<
=
=
=== Ay/4@@@@4r%   r*   c                N   | }t          d          D ]}t          |dd          }t          |t                    r|c S t          |dd          }t          |t                    rd|cxk    rdk     rn n|c S t          |dd          pt          |dd          }|||u r n|}dS )	z?Walk the error and its cause chain to find an HTTP status code.   r+   Nstatusd   r   	__cause____context__)rangegetattrr   rx   )rv   current_codecauses        r&   r   r     s    G1XX  wt44dC   	KKKw$//dC   	SD%6%6%6%63%6%6%6%6%6KKKd33\wwW[7\7\=EW,,E4r%   c                    t          | dd          }t          |t                    r|S t          | dd          }|=	 |                                }t          |t                    r|S n# t          $ r Y nw xY wi S )z8Extract the structured error body from an SDK exception.r   Nresponse)r  r   r>   r   rw   )rv   r   r  	json_bodys       r&   r   r     s    5&$''D$ uj$//H	 I)T** !  ! 	 	 	D	Is   *A) )
A65A6c                ~   | sdS dd}|                      di           }t          |t                    r|                     d          p|                     d          pd}t          |t                    r@|                                r,|                                dk    r|                                S |                     d	          }t          |t                    rj|                                                    d
          rCddl}	 |                    |          }n# |j        t          f$ r d}Y nw xY w ||          }|r|S |                      d          p|                      d          pd}t          |t          t          f          r+t          |                                          }|r|dk    r|S dS )z4Extract an error code string from the response body.r.   r8   r/   c                r   t          | t                    sdS |                     di           }t          |t                    r|                    d          p|                    d          pd}t          |t                    r@|                                r,|                                dk    r|                                S |                     d          p|                     d          pd}t          |t          t
          f          r+t          |                                          }|r|dk    r|S dS )zAExtract a code/type from a nested error payload dict (defensive).r.   rv   r  r   400r   )r   r>   r   r/   r   rx   )payloadpayload_errornestedr  texts        r&   _code_from_payloadz/_extract_error_code.<locals>._code_from_payload  s   '4(( 	2GR00mT** 	&"&&v..Q-2C2CF2K2KQrF&#&& &6<<>> &fllnnPU>U>U||~~%{{6""Egkk,&?&?E2dS#J'' 	t99??$$D rr%   rv   r  r   r!  r0   {r   Nr   )r8   r/   )r   r   r>   r/   r   
startswithr   r   r   r   rx   )	r   r&  	error_objr  r0   r   innernested_coder%  s	            r&   r   r     s    r     "%%I)T"" #}}V$$C	f(=(=CdC   	 TZZ\\ 	 djjlle6K6K::<<
 --	**gs## 	#(B(B3(G(G 	#KKK

7++()4   ,,U33K #"" 88F;txx55;D$c
## 4yy   	DEMMK2s   D" "D87D8c                   |r|                     di           }t          |t                    r[|                     dd          }t          |t                    r0|                                r|                                dd         S |                     dd          }t          |t                    r0|                                r|                                dd         S t          |           dd         S )z+Extract the most informative error message.rv   r0   r.   Nr   )r   r   r>   r/   r   )rv   r   r)  msgs       r&   r   r   H  s      %HHWb))	i&& 	)--	2..C#s## )		 )yy{{4C4((hhy"%%c3 	%CIIKK 	%99;;tt$$u::dsdr%   )rv   rw   r,   r/   r-   r/   rs   rx   rt   rx   ru   rx   r8   r(   )r+   rx   r   r/   r   r/   r   r>   r,   r/   r-   r/   rs   rx   rt   rx   ru   rx   r8   r   )r   r/   r8   r(   )r   r/   r   r/   r   r>   r,   r/   r-   r/   rs   rx   rt   rx   ru   rx   r8   r(   )r   r/   r   r/   r8   r   )
r   r/   r   r/   rs   rx   rt   rx   r8   r   )rv   rw   r8   r*   )rv   rw   r8   r>   )r   r>   r8   r/   )rv   rw   r   r>   r8   r/   )/r#   
__future__r   enumloggingdataclassesr   r   typingr   r   r   	getLoggerr    loggerEnumr
   r(   r   r   r   r   r  r   r   r   r   r   r   r   r  _THINKING_SIG_PATTERNSr  	frozensetr   r   r   r   r   r   r   r   r   r   r   r   r   r$   r%   r&   <module>r8     s^  	 	 # " " " " "   ( ( ( ( ( ( ( ( & & & & & & & & & &		8	$	$
( ( ( ( (TY ( ( (Z S S S S S S S S4   ,   &   	" 	" 	"    
 
 
 .% % % ! ! ! ! H	 	 	 (      4% % % !.$ $ $  .
 
 
      # $ $ $   4   4   0  l; l; l; l; l; l;v	 Y Y Y Y Y Yx   L Y Y Y Y Y Y|2 2 2 2nu u u ut   &   "/ / / /d     r%   