o
    2j                     @   sJ  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eZd	Zd
ZG dd deddZG dd deZg i dZeed< daedB ed< dee fddZdefddZdeeef defddZdefddZdefddZd ed!edB dedB fd"d#Zd ed$eddfd%d&Z dedB fd'd(Z!dS ))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                   @   s"   e Zd ZU dZeeef ed< dS )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__ r   r   ^/var/www/html/whisper/venv/lib/python3.10/site-packages/huggingface_hub/utils/_detect_agent.pyr
   4   s   
 r
   F)totalc                   @   s.   e Zd ZU dZee ed< eeef ed< dS )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   
 r   )r   r   _EMPTY_REGISTRY	_registryreturnc            	      C   s   t  } | dp	g }| dpi }| D ]+\}}|pi d}|r*t|r*|  S |D ]}tj|d |kr?|    S q,qdd | D }|D ]}tj|d   }rf||v rc|  S  dS qLdS )	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    c                 S   s   h | ]}|  qS r   )lower).0kr   r   r   	<setcomp>^   s    zdetect_agent.<locals>.<setcomp>unknownN)	_get_registrygetitems_env_vars_matchosenvironstripkeysr   )	registrystandard_varsr   
harness_idinfoenv_varsvarlowercased_harnessesvaluer   r   r   detect_agentI   s(   r3   c                   C   s
   t  duS )zDReturn `True` if the process is being invoked by an AI coding agent.N)r3   r   r   r   r   is_agenth   s   
r4   r/   c                 C   sD   |   D ]\}}tj|}|sq|dkr dS ||kr dS qdS )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$   )r/   r0   patternr2   r   r   r   r&   m   s   r&   c                   C   s@   t du rzt a W t S  ty   tjddd ta Y t S w t S )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.
    Nz+Could not resolve agent harnesses registry.Texc_info)r   _load_registry	Exceptionloggerdebugr   r   r   r   r   r#      s   r#   c                  C   sN   t j} t| td }r|S t  }durt| | |S t| dd }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staler   r   r   r9      s   
r9   rC   r=   c                 C   s   z;t j| s
W dS |durt t j|  |krW dS t| dd}t|W  d   W S 1 s4w   Y  W dS  tyL   t	j
ddd Y dS w )zBReturn the cached registry, or `None` if missing/stale/unreadable.Nutf-8encodingz/Could not read cached agent harnesses registry.Tr7   )r'   rC   existstimegetmtimeopenjsonloadr:   r;   r<   )rC   r=   fr   r   r   r?      s    (r?   r+   c                 C   s|   z,t | jjddd t| ddd}t|| W d    W d S 1 s%w   Y  W d S  ty=   tjddd Y d S w )NT)parentsexist_okwrG   rH   z)Could not cache agent harnesses registry.r7   )	r   parentmkdirrM   rN   dumpr:   r;   r<   )rC   r+   rP   r   r   r   rB      s   &rB   c                  C   sd   t jrdS zddlm}  |  jt j dtd}|  | W S  t	y1   t
jddd Y dS 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.Tr7   )r   HF_HUB_OFFLINE_httprW   r$   ENDPOINT_REGISTRY_FETCH_TIMEOUTraise_for_statusrN   r:   r;   r<   )rW   responser   r   r   rA      s   

rA   )"r   rN   r'   rK   pathlibr   typingr   r   r   r   r   
get_loggerr   r;   r@   r\   r
   r   r   r   r   r   r3   boolr4   r   r&   r#   r9   intr?   rB   rA   r   r   r   r   <module>   s.   
		