
    3j                     z   % S r SSKrSSKrSSKrSSKJr  SSKJrJr  SSK	J
r
  SSK	Jr  \R                  " \5      rS	rS
r " S S\SS9r " S S\5      r/ 0 S.r\\S'   Sq\S-  \S'   S\\   4S jrS\4S jrS\\\4   S\4S jrS\4S jrS\4S jrS\S\S-  S\S-  4S jrS\S\SS4S jr S\S-  4S  jr!g)!u  Detect whether the process is being invoked by an AI coding agent.

Detection is based on environment variables that AI agents set in their shell
sessions. `AI_AGENT` and `AGENT` are treated as a universal standard (any
tool can set its harness id there); the remaining checks are tool-specific and
ordered by priority (first match wins).

The list of known harnesses is maintained on the Hub and exposed at
`{ENDPOINT}/api/agent-harnesses`. We fetch it at most once a day and cache it
locally so the list can be updated without requiring a new client release.

Detection is entirely best-effort: there is no hardcoded list of harnesses. When
the registry cannot be fetched (and no cached copy is available), detection simply
reports "no agent". Any error while fetching/reading the registry is swallowed —
detection must never make a process fail.

More details: https://huggingface.co/docs/hub/agents-overview#register-your-agent-harness
    N)Path)Optional	TypedDict   )	constants   )loggingiQ    c                   .    \ rS rSr% Sr\\\4   \S'   Srg)HarnessInfo4   zbA single harness entry. `envVars` maps an env var name to a match pattern (see `_env_vars_match`).envVars N)	__name__
__module____qualname____firstlineno____doc__dictstr__annotations____static_attributes__r       ]/home/wildlama/miniconda3/lib/python3.13/site-packages/huggingface_hub/utils/_detect_agent.pyr   r   4   s    l#s(^r   r   F)totalc                   >    \ rS rSr% Sr\\   \S'   \\\	4   \S'   Sr
g)Registry:   zJThe agent harness registry, as served by `{ENDPOINT}/api/agent-harnesses`.standardEnvVars	harnessesr   N)r   r   r   r   r   listr   r   r   r   r   r   r   r   r   r   :   s    T#YC$%%r   r   )r   r    _EMPTY_REGISTRY	_registryreturnc                     [        5       n U R                  S5      =(       d    / nU R                  S5      =(       d    0 nUR                  5        H{  u  p4U=(       d    0 R                  S5      nU(       a  [        U5      (       a  Us  $ U H;  n[        R
                  R                  US5      R                  5       U:X  d  M7  Us  s  $    M}     UR                  5        Vs1 s H  owR                  5       iM     nnU HQ  n[        R
                  R                  US5      R                  5       R                  5       =n	(       d  MH  X;   a  U	s  $   g   gs  snf )aG  Return the id of the detected AI agent harness or `None`.

Harnesses are checked in registry order; for each one we match its env var
pattern(s) and, failing that, the standard `AI_AGENT` / `AGENT` vars
against the harness id. The first match wins. When a standard var is set to
an unrecognized value, `"unknown"` is returned.
r   r    r    unknownN)	_get_registrygetitems_env_vars_matchosenvironstripkeyslower)
registrystandard_varsr    
harness_idinfoenv_varsvarklowercased_harnessesvalues
             r   detect_agentr:   I   s    HLL!239rM[)/RI%OO-
JB##I.11 Czz~~c2&,,.*<!! !	 . 09~~/?@/?!GGI/?@JJNN3+11399;;5;,	   As    Ec                      [        5       SL$ )zDReturn `True` if the process is being invoked by an AI coding agent.N)r:   r   r   r   is_agentr<   h   s    >%%r   r5   c                     U R                  5        H<  u  p[        R                  R                  U5      nU(       d  M-  US:X  a    gX2:X  d  M<    g   g)zReturn `True` if any `(var, pattern)` from the harness matches the environment.

Supported patterns:
  - `"*"`: the variable is set to any non-empty value
  - `"<value>"`: the variable equals this exact value
*TF)r*   r,   r-   r)   )r5   r6   patternr9   s       r   r+   r+   m   sG     !(

s#c> ) r   c                      [         c   [        5       q [         $ [         $ ! [         a"    [        R	                  SSS9  [
        q  [         $ f = f)zReturn the harness registry, loading (and caching in-process) on first call.

Best-effort: any unexpected error degrades to an empty registry so detection
never raises.
z+Could not resolve agent harnesses registry.Texc_info)r#   _load_registry	Exceptionloggerdebugr"   r   r   r   r(   r(      sR     	(&(I 9  	(LLFQULV'I	(s   
 $A
Ac                      [         R                  n [        U [        S9=n(       a  U$ [	        5       =nb  [        X5        U$ [        U SS9=n(       a  U$ [        $ )zResolve the registry from the local cache or the Hub.

No hardcoded list: if the Hub is unreachable and no cached copy exists, an
empty registry is returned (i.e. no agent is detected).
)max_ageN)r   AGENT_HARNESSES_PATH_read_cached_registry_REGISTRY_TTL_SECONDS_fetch_registry_write_cached_registryr"   )pathcachedfetchedstales       r   rC   rC      se     ))D 't5JKKvK #$$1t- &dD99u9r   rN   rH   c                     [         R                  R                  U 5      (       d  gUb:  [        R                  " 5       [         R                  R	                  U 5      -
  U:  a  g[        U SS9 n[        R                  " U5      sSSS5        $ ! , (       d  f       g= f! [         a    [        R                  SSS9   gf = f)zBReturn the cached registry, or `None` if missing/stale/unreadable.Nutf-8encodingz/Could not read cached agent harnesses registry.TrA   )r,   rN   existstimegetmtimeopenjsonloadrD   rE   rF   )rN   rH   fs      r   rJ   rJ      s    	ww~~d##DIIK"''2B2B42H$HW#T$)Q99Q< *)) FQUVs:   $B <B $
B .B	B 
BB B C ?C r1   c                 
    [        U 5      R                  R                  SSS9  [        U SSS9 n[        R
                  " X5        S S S 5        g ! , (       d  f       g = f! [         a    [        R                  SSS9   g f = f)NT)parentsexist_okwrS   rT   z)Could not cache agent harnesses registry.rA   )	r   parentmkdirrY   rZ   dumprD   rE   rF   )rN   r1   r\   s      r   rM   rM      sl    QT
t<$g.!IIh" /.. Q@4PQs.   .A! AA! 
AA! A! !BBc                     [         R                  (       a  g SSKJn   U " 5       R	                  [         R
                   S3[        S9nUR                  5         UR                  5       $ ! [         a    [        R                  SSS9   gf = f)	zMFetch the registry from the Hub. Returns `None` when offline or on any error.Nr   )get_sessionz/api/agent-harnesses)timeoutz6Could not fetch agent harnesses registry from the Hub.TrA   )r   HF_HUB_OFFLINE_httpre   r)   ENDPOINT_REGISTRY_FETCH_TIMEOUTraise_for_statusrZ   rD   rE   rF   )re   responses     r   rL   rL      s    &=$$!!""67+ % 
 	!!#}} MX\]s   AA( (B	B	)"r   rZ   r,   rW   pathlibr   typingr   r   r&   r   r	   
get_loggerr   rE   rK   rj   r   r   r"   r   r#   r   r:   boolr<   r   r+   r(   rC   intrJ   rM   rL   r   r   r   <module>rr      s  &  	   &   
		H	% "   )5 &y & 13D D "	8d? !hsm >&$ &
d38n  $x   . cDj X_ Q Q QT QD r   