
    \j                     p   U d Z ddlZddlZddlZddlmZ ddlmZmZ ddl	m
Z
 ddl	mZ  ej                  e      Zd	Zd
Z G d ded      Z G d de      Zg i dZeed<   daedz  ed<   dee   fdZdefdZdeeef   defdZdefdZdefdZdededz  dedz  fdZdededdfdZ dedz  fd Z!y)!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                   &    e Zd ZU dZeeef   ed<   y)HarnessInfozbA single harness entry. `envVars` maps an env var name to a match pattern (see `_env_vars_match`).envVarsN)__name__
__module____qualname____doc__dictstr__annotations__     V/root/.hermes/venv/lib/python3.12/site-packages/huggingface_hub/utils/_detect_agent.pyr   r   4   s    l#s(^r   r   F)totalc                   6    e Zd ZU dZee   ed<   eeef   ed<   y)RegistryzJThe agent harness registry, as served by `{ENDPOINT}/api/agent-harnesses`.standardEnvVars	harnessesN)	r   r   r   r   listr   r   r   r   r   r   r   r   r   :   s    T#YC$%%r   r   )r   r   _EMPTY_REGISTRY	_registryreturnc                  b   t               } | j                  d      xs g }| j                  d      xs i }|j                         D ]i  \  }}|xs i j                  d      }|rt        |      r|c S |D ]9  }t        j
                  j                  |d      j                         |k(  s5|c c S  k |j                         D ch c]  }|j                          }}|D ]J  }t        j
                  j                  |d      j                         j                         x}	sB|	|v r|	c S  y yc c}w )a[  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_agentr6   I   s     HLL!239rM[)/RI%OO- "
DJB##I.1  	"Czz~~c2&,,.*<!!	"	" 09~~/?@!AGGI@@ JJNN3+11399;;5;,,	  As   D,c                      t               duS )zDReturn `True` if the process is being invoked by an AI coding agent.N)r6   r   r   r   is_agentr8   h   s    >%%r   r1   c                     | j                         D ]5  \  }}t        j                  j                  |      }|s(|dk(  r y||k(  s5 y y)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%   )r1   r2   patternr5   s       r   r'   r'   m   sP     !( W

s#c>G r   c                      t         	 t               a t         S t         S # t        $ r% t        j	                  dd       t
        a Y t         S w xY w)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                      t         j                  } t        | t              x}r|S t	               x}t        | |       |S t        | d      x}r|S t        S )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   r?   r?      sg     ))D 't5JKKvK #$$1tW- &dD99u9r   rJ   rD   c                 t   	 t         j                  j                  |       sy|8t        j                         t         j                  j	                  |       z
  |k\  ryt        | d      5 }t        j                  |      cddd       S # 1 sw Y   yxY w# t        $ r t        j                  dd       Y yw xY w)zBReturn the cached registry, or `None` if missing/stale/unreadable.Nutf-8encodingz/Could not read cached agent harnesses registry.Tr=   )r(   rJ   existstimegetmtimeopenjsonloadr@   rA   rB   )rJ   rD   fs      r   rF   rF      s    	ww~~d#DIIK"''2B2B42H$HW#T$) 	 Q99Q<	  	  	  FQUVs:   B 9B B )B>	B BB B  B76B7r-   c                    	 t        |       j                  j                  dd       t        | dd      5 }t	        j
                  ||       d d d        y # 1 sw Y   y xY w# t        $ r t        j                  dd       Y y w xY w)NT)parentsexist_okwrO   rP   z)Could not cache agent harnesses registry.r=   )	r   parentmkdirrU   rV   dumpr@   rA   rB   )rJ   r-   rX   s      r   rI   rI      sw    QT
t<$g. 	#!IIh"	# 	# 	# Q@4PQs.   4A" AA" AA" A" " BBc                     t         j                  ry	 ddlm}   |        j	                  t         j
                   dt              }|j                          |j                         S # t        $ r t        j                  dd       Y yw xY w)	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.Tr=   )r   HF_HUB_OFFLINE_httpra   r%   ENDPOINT_REGISTRY_FETCH_TIMEOUTraise_for_statusrV   r@   rA   rB   )ra   responses     r   rH   rH      s    &=$$!!""67+ % 
 	!!#}} MX\]s   AA& & B	B	)"r   rV   r(   rS   pathlibr   typingr   r   r"   r   r	   
get_loggerr   rA   rG   rf   r   r   r   r   r   r   r6   boolr8   r   r'   r$   r?   intrF   rI   rH   r   r   r   <module>rn      s  &  	   &   
		H	% "   )5 &y & 13D D "	8d? !hsm >&$ &
d38n  $x   . cDj X_ Q Q QT QD r   