+
    kHàjqx  ã                  ó:  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	t	^ RI
t
^ RIt^ RIHt ^ RIHtHt ^ RIHt ^ RIHt ^ RIHt ]P.                  ! ]4      t/ tR]R	&   / tR
]R&   / tR
]R&   RsR]R&   RsR]R&   Rs Rs!Rt"] ! R R4      4       t#/ t$R]R&   ]
PJ                  ! 4       t&]! RRR7      t'R]R&   ]! ](4      PS                  4       PT                  PT                  R,          R,          t+R R lt,R R  lt-R! R" lt./ t/R#]R$&   / t0R%]R&&   ]1! 4       t2R' R( lt3R) R* lt4R+ R, lt5R- R. lt6R/ R0 lt7R1R/R2 R3 llt8R4 R5 lt9R6R/R7 R8 llt:R9 R: lt;R; R< lt<R= R> lt=R? R@ lt>RA RB lt?RC RD lt@RERF/RG RH lltARI RJ ltBRK RL ltCRM RN ltDRO RP ltER# )Qu6  Provider module registry.

Provider profiles can live in three places:

1. Bundled plugins: ``plugins/model-providers/<name>/`` (shipped with hermes-agent)
2. User plugins: ``$HERMES_HOME/plugins/model-providers/<name>/``
3. Pip-installed plugins: distributions exposing a ``hermes_agent.plugins``
   entry point (``module:func`` callable or a self-registering ``module``)

Each plugin directory contains:
  - ``__init__.py`` â€” calls ``register_provider(profile)`` at import
  - ``plugin.yaml`` â€” manifest (name, kind: model-provider, version, description)

Discovery is lazy: the first call to ``get_provider_profile()`` or
``list_providers()`` imports the bundled and pip-installed plugins once per
process; the ``$HERMES_HOME`` plugins of the profile home bound at lookup time
load into that home's own layer, so one process serving several profiles
(multiplex gateway, Desktop ``serve``) resolves each profile's installs. User
plugins override bundled plugins on name collision, so third parties can
monkey-patch or replace any built-in profile without editing the repo.

For backward compatibility, ``providers/*.py`` files (other than ``base.py``
and ``__init__.py``) are still discovered via ``pkgutil.iter_modules``.
This lets out-of-tree users drop a single-file profile into an editable
install without the plugin dir structure. New profiles should prefer the
plugin layout.

Usage::

    from providers import get_provider_profile
    profile = get_provider_profile("nvidia")   # ProviderProfile or None
    profile = get_provider_profile("kimi")     # checks name + aliases
)ÚannotationsN)Ú
ContextVar)Ú	dataclassÚfield)ÚPath)ÚAny)ÚProviderProfileúdict[str, ProviderProfile]Ú	_REGISTRYúdict[str, str]Ú_ALIASESÚ_SOURCESú
str | NoneÚ_current_sourcezlist[ProviderProfile] | NoneÚ_PROVIDER_LIST_CACHEFg      ð?c                  óp   € ] tR t^Ct$ Rt]! ]R7      tR]R&   ]! ]R7      t	R]R&   Rt
R]R&   R	tR
]R&   RtR	# )Ú
_HomeLayerui  The ``$HERMES_HOME/plugins`` providers of ONE profile home.

One process serves many profiles (multiplex gateway, Desktop ``serve``) and each profile installs
its own plugins, so user plugins are keyed by the home bound at lookup time instead of the home
that happened to be bound at first discovery â€” that made a plugin installed in a secondary
profile ``Unknown provider`` in Desktop while the same profile worked in a terminal (#88143).
``stamps`` are the plugin dirs' mtimes: a directory added by ``hermes plugins install`` while the
process runs changes them, and the next lookup imports it without a restart.
)Údefault_factoryr	   Úregistryr   ÚaliasesÚtupleÚstampsNzfloat | NoneÚstamp_checked_at© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   Údictr   Ú__annotations__r   r   r   Ú__static_attributes__r   ó    Ú7/home/ubuntu/.hermes/hermes-agent/providers/__init__.pyr   r   C   s=   ‡ ññ ,1ÀÔ+F€HÐ(ÓFÙ#°DÔ9€Gˆ^Ó9Ø€FˆEÓØ%)Ð�l×)r"   r   zdict[str, _HomeLayer]Ú_HOME_LAYERSÚ_provider_registration_target)ÚdefaultzContextVar[_HomeLayer | None]Ú_REGISTRATION_TARGETÚpluginsúmodel-providersc               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚNoner   )Úformats   "r#   Ú__annotate__r0   b   s   € ÷ =ñ =˜Tñ =r"   c                 óê   € R F=  w  r\        \        P                  P                  V 4      VR4      pVf   K5   V! 4        K?  	  R#   \         d"   p\
        P                  RY4        Rp?Kj  Rp?ii ; i)a®  Mirror profiles into the ``hermes_cli`` snapshots (auth registry, picker catalog) that are loaded.

``hermes_cli.auth`` takes its own snapshot of ``list_providers()`` when it is imported. If a
plugin's imports pull that module in while :func:`_discover_providers` is still running, the
snapshot is partial and later plugins never reach the auth registry ("Unknown provider",
#102123). Calling back into auth once discovery is complete closes that window. Looked up via
``sys.modules`` on purpose: this layer must never import ``hermes_cli`` (that would run auth's
top-level code mid-scan and risk a circular import). Never raises: registration must not fail
because of the auth mirror.
Nz%s sync skipped: %s))zhermes_cli.authÚsync_plugin_provider_registry)z hermes_cli.models_catalog_staticÚsync_plugin_provider_catalog)ÚgetattrÚsysÚmodulesÚgetÚ	ExceptionÚloggerÚdebug)ÚmoduleÚattrÚsyncÚexcs       r#   Ú_sync_auth_registryr?   b   sc   € ó‰ˆô ”s—{‘{—‘ vÓ.°°dÓ;ˆØŠ<Ùð	=ÙŽFóøô ô 	=Ü�L‰LÐ.°×<Ò<ûð	=ús   ¹AÁA2ÁA-Á-A2c               ó    € V ^8„  d   QhRRRR/# )r,   Úprofiler   r-   r.   r   )r/   s   "r#   r0   r0   z   s   € ÷ ñ ˜ð °4ñ r"   c                óÄ  € \         P                  4       pVeF   WP                  V P                  &   V P                   F  pV P                  VP                  V&   K  	  M\V \
        V P                  &   \        ;'       g    R\        V P                  &   V P                   F  pV P                  \        V&   K  	  Rs	\        '       d   \        '       g   \        4        R# R# R# )uM  Register a provider profile by name and aliases.

Later registrations with the same name replace earlier ones â€” so user
plugins under ``$HERMES_HOME/plugins/model-providers/`` can override
bundled profiles without editing repo code. A registration made while a
``$HERMES_HOME`` plugin is being imported lands in that home's layer.
NÚruntime)r'   r7   r   Únamer   r
   r   r   r   r   Ú_discoveredÚ_discoveringr?   )rA   ÚlayerÚaliass   &  r#   Úregister_providerrI   z   s¥   € ô !×$Ñ$Ó&€EØÒØ'.�‰�w—|‘|Ñ$Ø—_”_ˆEØ#*§<¡<ˆE�M‰M˜%Ó ò %ð #*Œ	�'—,‘,ÑÜ!0×!=Ð!=°IŒ�—‘ÑØ—_”_ˆEØ%Ÿl™lŒH�U‹Oñ %à#Ðßƒ{Ÿ<›<ÜÖñ (�{r"   c               ó    € V ^8„  d   QhRRRR/# )r,   rD   Ústrr-   r   r   )r/   s   "r#   r0   r0   ’   s   € ÷ 
#ñ 
#˜#ð 
# *ñ 
#r"   c                óÔ   € \        4       pVP                  P                  V 4      ;'       g    \        P                  W 4      pW!P                  9   d   R# \
        P                  V4      # )u  Discovery source of the profile currently registered under *name* (see ``_SOURCES``), or None.

``"user"`` is what lets a ``$HERMES_HOME`` plugin re-registering a bundled name win in
``hermes_cli.auth.PROVIDER_REGISTRY`` too â€” a bundled profile never rewrites a built-in row.
Úuser)Ú_home_layerr   r7   r   r   r   )rD   rG   Ú	canonicals   &  r#   Úprovider_sourcerP   ’   sL   € ô ‹M€EØ—‘×!Ñ! $Ó'×CÐC¬8¯<©<¸Ó+C€IØ—N‘NÔ"ÙÜ�<‰<˜	Ó"Ð"r"   zdict[str, dict[str, bool]]Ú_NAMED_CUSTOM_MEMOzdict[str, Any]Ú_NAMED_CUSTOM_MEMO_SIGc               ó(   € V ^8„  d   QhRRRRRRRR/# )r,   rD   rK   ÚhomeúPath | NoneÚhkeyr-   Úboolr   )r/   s   "r#   r0   r0   «   s(   € ÷ ñ  Sð °ð À3ð È4ñ r"   c                ó`  € ^ RI Hp  Ve   V! VR,          P                  4       4      MRp\        P                  V4      pVe    \        P                  V\        4      V8w  d   / pV\        V&   V\        V&   W9   d	   WP,          # ^ RIH	p V! V 4      WP&   WP,          #   \         d    Rp L�i ; i)zK``has_named_custom_provider`` memoized on the home's config file signature.)Úfile_signatureNzconfig.yaml)Úhas_named_custom_provider)
ÚutilsrY   ÚstatÚOSErrorrQ   r7   rR   Ú_NAMED_CUSTOM_MEMO_NO_SIGÚ"hermes_cli.runtime_provider_customrZ   )rD   rT   rV   rY   ÚsigÚmemorZ   s   &&&    r#   Ú_has_named_custom_providerrb   «   s­   € å$ðØ?CÒ?O‰n˜d ]Õ2×8Ñ8Ó:Ô;ÐUYˆô ×!Ñ! $Ó'€DØ‚|Ô-×1Ñ1°$Ô8QÓRÐVYÔYØˆØ#'Ô˜4Ñ Ø'*Ô˜tÑ$Ø„|Ø�zÐÝLá*¨4Ó0€D�JØ�:Ðøô ô ØŠðús   ˆ#B ÂB-Â,B-c               ó    € V ^8„  d   QhRRRR/# )r,   rD   rK   r-   úProviderProfile | Noner   )r/   s   "r#   r0   r0   À   s   € ÷ &ñ &˜sð &Ð'=ñ &r"   c                ó   a€ ^ RI Hp V! 4       '       d   R# \        '       g   \        4        \	        4       w  or#\        SW#4      pR V3R llpV! V 4      p\        V \        4      ;'       d     V P                  4       P                  R4      pVf-   V'       g%   V'       g   \        SW#RR7      '       d	   V! V 4      pVf   V'       d	   V! R4      pVf9   \        V \        4      '       d#   V'       g   \        WV4      '       d	   V! R4      pV# )	zsLook up a provider profile by name or alias.

Returns None if the provider has no profile (falls back to generic).
©Úsafe_worker_enabledNc               ó    € V ^8„  d   QhRRRR/# )r,   ÚnrK   r-   rd   r   )r/   s   "r#   r0   Ú*get_provider_profile.<locals>.__annotate__Î   s   € ÷ Iñ I�#ð IÐ0ñ Ir"   c                óä   <€ SP                   P                  V 4      ;'       g    \        P                  W 4      pSP                  P                  V4      ;'       g    \        P                  V4      # ©N)r   r7   r   r   r
   )ri   rO   rG   s   & €r#   ÚlookupÚ$get_provider_profile.<locals>.lookupÎ   sN   ø€ Ø—M‘M×%Ñ% aÓ(×>Ð>¬H¯L©L¸Ó,>ˆ	Ø�~‰~×!Ñ! )Ó,×HÐH´	·±¸iÓ0HÐHr"   zcustom:T©ÚforceÚcustom)Úagent.safe_worker_policyrg   rE   Ú_discover_providersÚ_bound_home_layerÚ_refresh_home_layerÚ
isinstancerK   ÚlowerÚ
startswithrb   )	rD   rg   rT   ÚkeyÚcheckedrm   rA   Úis_custom_routerG   s	   &       @r#   Úget_provider_profiler|   À   sÛ   ø€ õ
 =á×ÒÙß‹;ÜÔÜ(Ó*Ñ€Eˆ4Ü! %¨Ó3€G÷Ið Iñ �T‹l€Gô
 ! ¤sÓ+×RÐR°·
±
³×0GÑ0GÈ	Ó0R€OØ‚Ÿ·wÜ˜u d°t×<Ó<Ù˜T“lˆGð ‚Ÿ?Ù˜Ó"ˆð
 ‚œ: d¬C×0Ò0¿Ü% d°#×6Ò6Ù˜XÓ&ˆGØ€Nr"   c               ó$   € V ^8„  d   QhRRRRRR/# )r,   ÚproviderrK   Úmodelr-   rW   r   )r/   s   "r#   r0   r0   é   s&   € ÷ `ñ `¸ð `ÀCð `ÈDñ `r"   c                óâ  € \        T ;'       g    R4      P                  4       P                  4       p\        V4      pVe   VP                  RJ d   R# ^ RIHp V! V4      '       g   R# \        T;'       g    R4      P                  4       P                  R4      w  rVpV'       d	   V'       g   R# \        VP                  4       P                  4       4      pVRJ;'       d    VP                  RJ # )aÌ  Whether an active route or its aggregator-targeted model rejects image tool parts.

Routing aggregators such as ``openrouter`` send vendor-prefixed model IDs
(for example, ``xiaomi/mimo-v2.5``), but their own profile cannot describe
every routed provider's tool-message compatibility. Preserve the transport
profile as the default and consult a registered target profile only for
routing aggregators. Missing or unrecognized identities deliberately fail open.
Ú NFT)Úis_routing_aggregatorÚ/)rK   Ústriprw   r|   Úsupports_vision_tool_messagesÚhermes_cli.providersr‚   Ú	partition)	r~   r   Úprovider_namerA   r‚   Útarget_nameÚ	separatorÚ_Útarget_profiles	   &&       r#   Ú)routed_model_rejects_vision_tool_messagesr�   é   sÅ   € ô ˜Ÿ˜ BÓ'×-Ñ-Ó/×5Ñ5Ó7€MÜ" =Ó1€GØÒ˜w×DÑDÈÓMÙõ ;Ù  ×/Ò/Ùä # E§K K¨RÓ 0× 6Ñ 6Ó 8× BÑ BÀ3Ó GÑ€K˜AßŸKÙÜ)¨+×*;Ñ*;Ó*=×*CÑ*CÓ*EÓF€NØ Ð%×_Ð_¨.×*VÑ*VÐZ_Ð*_Ð_r"   c               ó   € V ^8„  d   QhRR/# )r,   r-   zlist[ProviderProfile]r   )r/   s   "r#   r0   r0     s   € ÷ ñ Ð-ñ r"   c                 ód  € ^ RI Hp  V ! 4       '       d   . # \        '       g   \        4        \	        4       p\
        fg   \        4       p. p\        P                  4        F@  p\        V4      V9  g   K  VP                  \        V4      4       VP                  V4       KB  	  Vs\
         Uu. uF!  qUP                  VP                  9  g   K  VNK#  	  ppTP                  VP                  P                  4        Uu/ uF  p\        V4      VbK  	  upP                  4       4       V# u upi u upi )zšReturn all registered provider profiles (one per canonical name); the bound home's
``$HERMES_HOME`` plugins shadow process-wide profiles of the same name.rf   )rr   rg   rE   rs   rN   r   Úsetr
   ÚvaluesÚidÚaddÚappendrD   r   Úextend)rg   rG   ÚseenÚcacherA   ÚpÚresults          r#   Úlist_providersrš     sê   € õ =á×ÒØˆ	ç‹;ÜÔÜ‹M€EÜÒ#ä›ˆØ')ˆÜ ×'Ñ'Ö)ˆGÜ�'‹{ $Ö&Ø—‘œ˜G›Ô%Ø—‘˜WÖ%ñ *ð  %ÐÝ-ÓNÑ-�A·±¸u¿~¹~Ñ1M�aˆaÑ-€FÐNØ
‡M�M U§^¡^×%:Ñ%:Ô%<Ó=Ñ%< ”2�a“5˜!’8Ñ%<Ñ=×DÑDÓFÔGØ€Mùò OùÚ=s   Â,D(ÃD(Ã<D-c               ó   € V ^8„  d   QhRR/# )r,   r-   zset[str]r   )r/   s   "r#   r0   r0     s   € ÷ ñ  ñ r"   c                 óB  € \        4       p \        4        F7  p VP                  4       '       g   V P                  VP                  4       K7  K9  	  V #   \
         dB    \        P                  RTP                  RR7       T P                  TP                  4        Kˆ  i ; i)an  Registered profiles that discovery surfaces (provider pickers, setup lists, the accounts tab)
must not offer: pre-release ones the user has not opted into.

Resolution never consults this: an unlisted profile still resolves, authenticates and serves
turns by name. A raising ``listed()`` counts as unlisted, because a broken gate must never
advertise a dark launch.
z&provider %s listed() raised; hiding itT)Úexc_info)r�   rš   Úlistedr“   rD   r8   r9   r:   )ÚhiddenrA   s     r#   Úunlisted_provider_namesr      s   € ô “u€FÜ!Ö#ˆð	%Ø—>‘>×#Ò#Ø—
‘
˜7Ÿ<™<Ö(ñ $ñ $ð €Møô ô 	%Ü�L‰LÐAÀ7Ç<Á<ÐZ^ˆLÔ_Ø�J‰J�w—|‘|×$ð	%ús   ™1AÁABÂBÚforce_stamp_checkc               ó    € V ^8„  d   QhRRRR/# )r,   r¡   rW   r-   r   r   )r/   s   "r#   r0   r0   0  s   € ÷ ñ  dð °zñ r"   c                ó:   € \        4       w  rp\        WW0R7       V# )zRThe layer for the home bound right now, importing plugin dirs it has not seen yet.ro   )rt   ru   )r¡   rG   rT   ry   s   $   r#   rN   rN   0  s   € ä(Ó*Ñ€E�Ü˜ SÕBØ€Lr"   c               ó   € V ^8„  d   QhRR/# )r,   r-   z#tuple[_HomeLayer, Path | None, str]r   )r/   s   "r#   r0   r0   7  s   € ÷ ñ Ð>ñ r"   c                 ó  €  ^ RI Hp Hp V ! 4       pV! V4      p\        ;_uu_ 4        \
        P                  V4      pVf   \        4       ;p\
        V&   RRR4       XW#3#   \         d    RRr2 LWi ; i  + '       g   i     L(; i)é    )Úget_hermes_homeÚhermes_home_keyNr�   )Úhermes_constantsr§   r¨   r8   Ú_HOME_LAYERS_LOCKr$   r7   r   )r§   r¨   rT   ry   rG   s        r#   rt   rt   7  s{   € ðßEáÓ ˆÙ˜dÓ#ˆ÷ 
Ö	Ü× Ñ  Ó%ˆØŠ=Ü(2«Ð4ˆE”L Ñ%÷ 
ð �$ÐÐøô ô Ø˜"Šcðúç	×	ús   ‚A  §-A4Á A1Á0A1Á4B	rp   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
r,   rG   r   rT   rU   ry   rK   rp   rW   r-   r   )r/   s   "r#   r0   r0   F  s1   € ÷ ñ ˜zð °ð À3ð ÐRVð Ðcgñ r"   c               óR  € \         P                  ! 4       pVe2   V'       g,   V P                  e   W@P                  ,
          \        8¼  g   R# \	        V4      pWPP
                  8w  d:   \        W4       WPn        W@n        \        '       d   \        '       g   \        4        W@n        R# )aL  Re-stat the layer's plugin dirs when due (or *force*d); True when it stat'ed this call.

Stamps are read before the scan: a plugin that lands mid-scan changes them and the next
check picks it up. Checking on a short cadence keeps a newly installed plugin discoverable
without making every model lookup perform two filesystem stats.
FT)
ÚtimeÚ	monotonicr   Ú_PLUGIN_DIR_STAMP_TTL_SECONDSÚ_plugin_dir_stampsr   Ú_scan_home_layerrE   rF   r?   )rG   rT   ry   rp   Únowr   s   &&&$  r#   ru   ru   F  sz   € ô �.Š.Ó
€CØ‚|ßØ×!Ñ!Ò)Ø×'Ñ'Õ'Ô+HÔHáÜ Ó%€FØ—‘ÔÜ˜Ô$ØŒð
 "%Ôß‹;Ÿ|›|ÜÔ!Ø ÔÙr"   c               ó    € V ^8„  d   QhRRRR/# )r,   rT   r   r-   r   r   )r/   s   "r#   r0   r0   c  s   € ÷ Rñ R˜Tð R eñ Rr"   c                óX   € R R lpV! V R,          4      V! V R,          R,          4      3# )z[mtimes of ``plugins/`` and ``plugins/model-providers/``: they change when a child is added.c               ó   € V ^8„  d   QhRR/# )r,   Úpathr   r   )r/   s   "r#   r0   Ú(_plugin_dir_stamps.<locals>.__annotate__e  s   € ÷ ñ �Dñ r"   c                óh   €  \         P                  ! V 4      P                  #   \         d     R # i ; irl   )Úosr\   Úst_mtime_nsr]   )r¶   s   &r#   ÚstampÚ!_plugin_dir_stamps.<locals>.stampe  s-   € ð	Ü—7’7˜4“=×,Ñ,Ð,øÜô 	Úð	ús   ‚" ¢1°1r(   r)   r   )rT   r»   s   & r#   r°   r°   c  s.   € õñ
 �$˜Õ"Ó#¡U¨4°)Õ+;Ð>OÕ+OÓ%PÐQÐQr"   c               ó   € V ^8„  d   QhRR/# ©r,   r-   rU   r   )r/   s   "r#   r0   r0   m  s   € ÷ ñ ˜;ñ r"   c                 ó’   €  ^ RI Hp  V ! 4       R,          R,          pVP                  4       '       d   V# R#   \         d     R# i ; i)z>Return ``$HERMES_HOME/plugins/model-providers/`` if it exists.©r§   r(   r)   N©r©   r§   Úis_dirr8   ©r§   Úds     r#   Ú_user_plugins_dirrÅ   m  sD   € ðÝ4áÓ 	Õ)Ð,=Õ=ˆØ—H‘H—J’JˆqÐ( DÐ(øÜô Úðús   ‚07 ³7 µ7 ·AÁAc               ó   € V ^8„  d   QhRR/# r¾   r   )r/   s   "r#   r0   r0   x  s   € ÷ ñ  ñ r"   c                 ó„   €  ^ RI Hp  V ! 4       R,          pVP                  4       '       d   V# R#   \         d     R# i ; i)uß   Return ``$HERMES_HOME/plugins/`` if it exists.

This is where ``hermes plugins install`` clones a plugin â€” flat, one
directory per plugin, NOT under ``model-providers/``. See
:func:`_discover_installed_provider_plugins`.
rÀ   r(   NrÁ   rÃ   s     r#   Ú_installed_plugins_dirrÈ   x  s>   € ðÝ4áÓ 	Õ)ˆØ—H‘H—J’JˆqÐ( DÐ(øÜô Úðús   ‚)0 ¬0 ®0 °?¾?c               ó    € V ^8„  d   QhRRRR/# )r,   Ú
plugin_dirr   r-   rW   r   )r/   s   "r#   r0   r0   ˆ  s   € ÷  ñ  ¨dð  °tñ  r"   c                ó   € R EF"  pW,          pVP                  4       '       g   K$   VP                  RRR7      p ^ RIHp T! T4      p\        T\        4      '       d/   \        TP                  RR4      4      P                  4       R8H  u #  TP                  4        F‚  pTP                  4       pTP                  R	4      '       g   R
T9  d   K3  TP                  R
4      w  r‰p
TP                  4       R8X  g   K^  T
P                  4       P                  R4      R8H  u u # 	   R# 	  R#   \         d      R# i ; i  \         d     L½i ; i)u[  Whether ``plugin_dir``'s manifest declares ``kind: model-provider``.

Only that kind is imported from the flat install directory â€” every other
plugin there belongs to ``PluginManager``, which owns its lifecycle and
consent flow. Parsed with ruamel.yaml when available, falling back to a line
scan so provider discovery never hard-depends on it.
úutf-8Úreplace)ÚencodingÚerrorsF)Úfast_safe_loadÚkindr�   zmodel-providerÚ#Ú:z"')zplugin.yamlz
plugin.yml)Úis_fileÚ	read_textr8   r[   rÐ   rv   r   rK   r7   r„   Ú
splitlinesrx   r‡   )rÊ   ÚfilenameÚmanifestÚtextrÐ   ÚdataÚlineÚstrippedry   r‹   Úvalues   &          r#   Ú_declares_model_provider_kindrÞ   ˆ  s4  € ô 2ˆØÕ(ˆØ×Ñ×!Ò!Ùð	Ø×%Ñ%¨w¸yÐ%ÓIˆDð	Ý,á! $Ó'ˆDÜ˜$¤×%Ò%Ü˜4Ÿ8™8 F¨BÓ/Ó0×6Ñ6Ó8Ð<LÑLÒLð &ð —O‘OÖ%ˆDØ—z‘z“|ˆHØ×"Ñ" 3×'Ò'¨3°hÔ+>ÙØ$×.Ñ.¨sÓ3‰MˆC�EØ�y‰y‹{˜fÖ$Ø—{‘{“}×*Ñ*¨5Ó1Ð5EÑEÔEñ &ò ñ/ 2ñ0 øô% ô 	Ûð	ûô ô 	Ùð	ús#   ¨D,¼AD?Ä,D<Ä;D<Ä?EÅEc               ó$   € V ^8„  d   QhRRRRRR/# )r,   rG   r   ry   rK   r-   r.   r   )r/   s   "r#   r0   r0   «  s!   € ÷ )ñ )˜Jð )¨Sð )°Tñ )r"   c                óÆ  € \         P                  V 4      \        r2Rs \        4       pVej   \	        VP                  4       4       FL  pVP                  4       '       g   K  VP                  P                  R4      '       d   K>  \        VRVR7       KN  	  \        4       pVeŒ   \	        VP                  4       4       Fn  pVP                  4       '       d3   VP                  P                  R4      '       g   VP                  R8X  d   KM  \        V4      '       g   K`  \        VRVR7       Kp  	  \         P                  V4       VsR#   \         P                  T4       Tsi ; i)a›  Import the bound home's not-yet-imported provider plugins into *layer*.

``$HERMES_HOME/plugins/model-providers/<name>/`` first, then plugins cloned flat by
``hermes plugins install`` into ``$HERMES_HOME/plugins/<name>/`` that declare
``kind: model-provider`` (PluginManager owns every other kind there). Per-home module names
let two profiles carry the same plugin without aliasing each other's registrations.
TNrM   )Úhome_keyr)   ©r‹   Ú.)r'   r�   rF   rÅ   ÚsortedÚiterdirrÂ   rD   rx   Ú_import_plugin_dirrÈ   rÞ   Úreset)rG   ry   ÚtokenÚprior_discoveringÚuser_dirÚchildÚinstalled_dirs   &&     r#   r±   r±   «  s  € ô  4×7Ñ7¸Ó>ÄÐØ€Lð)Ü$Ó&ˆØÒÜ × 0Ñ 0Ó 2Ö3�Ø—<‘<—>”>¨%¯*©*×*?Ñ*?À
×*KÔ*KÜ& u¨f¸s×Cñ 4ô /Ó0ˆØÒ$Ü × 5Ñ 5Ó 7Ö8�Ø—|‘|—~’~¨¯©×)>Ñ)>¸z×)JÒ)JÈeÏjÉjÐ\mÔNmÙÜ0°×7Ô7Ü& u¨f¸s×Cñ	 9ô 	×"Ñ" 5Ô)Ø(Šøô 	×"Ñ" 5Ô)Ø(‰ús   ž=E Á E ÂBE ÄE ÅE c               ó$   € V ^8„  d   QhRRRRRR/# )r,   rÊ   r   rá   rK   r-   r   )r/   s   "r#   r0   r0   È  s&   € ÷ Qñ Q $ð Q°#ð Q¸#ñ Qr"   c                óº   € \         P                  ! VP                  R 4      4      P                  4       R,          pRV RV P                  P                  RR4       2# )rÌ   :Né
   NÚ_hermes_user_provider_r‹   Ú-)ÚhashlibÚsha1ÚencodeÚ	hexdigestrD   rÍ   )rÊ   rá   Údigests   && r#   Ú_user_module_namer÷   È  sL   € Ü�\Š\˜(Ÿ/™/¨'Ó2Ó3×=Ñ=Ó?ÀÕD€FØ# F 8¨1¨Z¯_©_×-DÑ-DÀSÈ#Ó-NÐ,OÐPÐPr"   rá   r�   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r,   rÊ   r   ÚsourcerK   rá   r-   r.   r   )r/   s   "r#   r0   r0   Í  s)   € ÷ 4ñ 4 4ð 4°ð 4À3ð 4ÐPTñ 4r"   c               óÜ  € V R,          pVP                  4       '       g   R# VR8w  dF   ^ RIHpHp V! 4       V8X  d2   ^ RIHp Vs V! V \        W4      4       F  p\        V4       K  	  RsR# VR8X  d!   RV P                  P                  RR	4       2p	M\        W4      p	V	\        P                  9   d   R# Vs \         P"                  P%                  W“\'        V 4      .R
7      p
V
e   V
P(                  f    RsR# \         P"                  P+                  V
4      pV\        P                  V	&   V
P(                  P-                  V4       RsR#   \         d-   p\        P                  RT P                  T4        Rp?ELRp?ii ; i  Rsi ; i  \         dL   p\        P                  RYP                  T4       \        P                  P/                  T	R4        Rp?L–Rp?ii ; i  Rsi ; i)z‘Import a single plugin directory so it self-registers.

``source`` is "bundled" or "user"; it is recorded per registered profile (``_SOURCES``).
z__init__.pyNÚbundled)ÚISOLATION_HOSTÚisolation_mode)Úload_hosted_profilesz=Failed to load user provider plugin %s in the plugin host: %szplugins.model_providers.rñ   r‹   )Úsubmodule_search_locationsz(Failed to load %s provider plugin %s: %s)ÚexistsÚhermes_cli.plugin_isolationrü   rý   Úhermes_cli.plugin_host_profilesrþ   r   r÷   rI   r8   r9   ÚwarningrD   rÍ   r5   r6   Ú	importlibÚutilÚspec_from_file_locationrK   ÚloaderÚmodule_from_specÚexec_moduleÚpop)rÊ   rù   rá   Ú	init_filerü   rý   rþ   rA   r>   Úmodule_nameÚspecr;   s   &&$         r#   ræ   ræ   Í  sµ  € ð ˜]Õ*€IØ×Ñ×ÒÙØ�ÔßNÙÓ˜~Ô-ÝLØ$ˆOð'Ù3°JÔ@QÐR\Ó@gÖh�GÜ% gÖ.ñ  ið #'�Ùð �ÔØ0°·±×1HÑ1HÈÈcÓ1RÐ0SÐT‰ä'¨
Ó=ˆà”c—k‘kÔ!Ùà€OðÜ�~‰~×5Ñ5ØÄÀJÃÐ?Pð 6ó 
ˆð Š<˜4Ÿ;™;Ò.Øð Šô —‘×0Ñ0°Ó6ˆØ#)Œ�‰�KÑ Ø�‰×Ñ Ô'ð ŠøôG ô 5Ü—‘Ð^Ø)Ÿ™°÷5ò 5ûð5ûð #'‘ûô2 ô +Ü�‰Ø6¸ÇÁÐQTô	
ô 	�‰�‰˜ T×*Ñ*ûð	+ûð ‰ús\   Á$E Â:=F Ã<AF ÅFÅ!E?Å9F Å?FÆF ÆFÆG$ÆAGÇG' ÇG$Ç$G' Ç'G+c               ó   € V ^8„  d   QhRR/# r+   r   )r/   s   "r#   r0   r0     s   € ÷ dñ d¨ñ dr"   c                 óˆ  €  ^ RI Hp   ^ RIHpHp T! 4       pT! 4       pT'       g   R# Rp T P                  4       p\        TR4      '       d   \        TP                  TR7      4      pM\        TP                  T. 4      4      p T Fâ  p	T	P                  T9  g   T	P                  T9   d#   \        P                  RT	P                  4       KG  ^ RIHp
 T
! R	T	P                  : 24      pT'       d   \        P#                  R
T4       Kƒ   T	P%                  4       p\'        T4      '       g   K§  \)        T4      '       d#   \        P                  RT	P                  4       KÚ   T! 4        Kä  	  R#   \         d     R# i ; i  \         d    R\        4       rC EL|i ; i  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i  \         d.   p\        P#                  RT	P                  T4        Rp?EKy  Rp?ii ; i  \         d.   p\        P#                  RT	P                  T4        Rp?EK´  Rp?ii ; i)uÆ  Import pip-installed provider plugins via the ``hermes_agent.plugins``
entry-point group so they self-register.

A distribution ships::

    [project.entry-points."hermes_agent.plugins"]
    acme-inference = "acme_hermes_plugin:register"

The target may be either a **callable** (``module:func`` â€” invoked with no
args; typically calls ``register_provider(profile)``) or a **module**
(``module`` â€” imported for its module-level ``register_provider`` side
effect, mirroring the directory-plugin ``__init__.py`` contract).

Gating and safety:

* **Opt-in.** Entry-point plugins are subject to the same
  ``plugins.enabled`` allow-list (and ``plugins.disabled`` deny-list) the
  general PluginManager enforces â€” a pip package is never imported just
  because it is installed. An entry point whose name is not enabled is
  skipped without loading.
* **Provider targets only.** The ``hermes_agent.plugins`` group is shared
  with general plugins whose target is ``register(ctx)``. Callables that
  require arguments are skipped here (the PluginManager owns them);
  provider registration hooks take no arguments by contract.

Failures are swallowed per-entry (a broken third-party package must not
break provider discovery) and logged at warning level. This scan runs
first, so filesystem plugins (bundled + ``$HERMES_HOME``) keep their
documented override precedence via last-writer-wins in
``register_provider()`` â€” a pip package cannot hijack a first-party
provider name.
N)Ú_get_disabled_pluginsÚ_get_enabled_pluginszhermes_agent.pluginsÚselect)Úgroupz%entry-point provider scan skipped: %sz6entry-point provider %r skipped: not enabled in config)Úin_process_import_refusalz$pip-installed model-provider plugin z%sz1Failed to load entry-point provider plugin %r: %szjentry-point %r skipped by provider scan: target requires arguments (general plugin owned by PluginManager)z7Entry-point provider plugin %r raised on invocation: %s)Úimportlib.metadataÚmetadatar8   Úhermes_cli.pluginsr  r  r�   Úentry_pointsÚhasattrÚlistr  r7   r9   r:   rD   r  r  r  ÚloadÚcallableÚ_requires_arguments)Ú_mdr  r  ÚenabledÚdisabledr  ÚepsÚ	group_epsr>   Úepr  ÚrefusalÚloadeds                r#   Ú_discover_entry_point_providersr&    så  € ðBÝ(ð(ßRá&Ó(ˆÙ(Ó*ˆ÷ Ùà"€Eð	Ø×ÑÓ ˆä�3˜×!Ò!Ü˜SŸZ™Z¨e˜ZÓ4Ó5‰Iä˜SŸW™W U¨BÓ/Ó0‰Ió
 ˆØ�7‰7˜'Ô! R§W¡W°Ô%8Ü�L‰LØHÈ"Ï'É'ôñ ÝIÙ+Ð.RÐSU×SZÑSZÑR]Ð,^Ó_ˆßÜ�N‰N˜4 Ô)Ùð	Ø—W‘W“YˆFô �F×ÔÜ" 6×*Ò*Ü—‘ðHà—G‘Gôñ
 ðÙ–óA øô7 ô Úðûô ô (Ø ¤#£%“ð(ûô ô Ü�‰Ð<¸cÔBÝûðûô" ô 	Ü�N‰NØCÀRÇWÁWÈcôö ûð		ûô( ô Ü—‘ØMØ—G‘GØ÷ó ûðúso   ‚E0 ‰F ¬=F Á*F ÄGÅ#H	Å0E?Å>E?ÆFÆFÆGÆ*GÇGÇHÇ!HÈHÈ	IÈ!H<È<Ic               ó   € V ^8„  d   QhRR/# )r,   r-   rW   r   )r/   s   "r#   r0   r0   k  s   € ÷ ñ ˜tñ r"   c                ó–  € ^ RI p VP                  V 4      pTP                  P                  4        F|  pTP                  TP                  P                  TP                  P                  TP                  P                  39   g   KU  TP                  TP                  P                  J g   K{   R# 	  R#   \        \        3 d     R# i ; i)a>  True when ``fn`` cannot be called with zero arguments.

Used to distinguish provider registration hooks (zero-arg by contract)
from general plugin hooks (``register(ctx)``) sharing the same entry-point
group. Unintrospectable callables (C extensions) are treated as zero-arg
and left to the per-entry exception guard.
NFT)ÚinspectÚ	signatureÚ	TypeErrorÚ
ValueErrorÚ
parametersr‘   rÑ   Ú	ParameterÚPOSITIONAL_ONLYÚPOSITIONAL_OR_KEYWORDÚKEYWORD_ONLYr&   Úempty)Úfnr)  r`   Úparams   &   r#   r  r  k  s®   € ó ðØ×Ñ Ó#ˆð —‘×&Ñ&Ö(ˆØ�:‰:Ø×Ñ×-Ñ-Ø×Ñ×3Ñ3Ø×Ñ×*Ñ*ð
ö 
ð �m‰m˜w×0Ñ0×6Ñ6Õ6Úñ )ñ øô ”zÐ"ô Úðús   †B3 Â3CÃCc               ó   € V ^8„  d   QhRR/# r+   r   )r/   s   "r#   r0   r0   ƒ  s   € ÷ ñ ˜Tñ r"   c                 ó¤   € ^ RI Hp  V ! 4       '       d   R# \        '       d   R# RsRs \	        4        Rs\        4        R#   Rs\        4        i ; i)a²  Populate the process-wide registry by importing every provider plugin.

Order:
  1. Bundled plugins at ``<repo>/plugins/model-providers/<name>/``
  2. Legacy per-file modules at ``providers/<name>.py`` (back-compat)

Each step imports its plugins, which call ``register_provider()`` at
module-level. Later steps win on name collision. ``$HERMES_HOME`` plugins are
per profile home and load through :func:`_home_layer` at lookup time.
rf   NTF)rr   rg   rE   rF   Ú_run_discovery_stepsr?   rf   s    r#   rs   rs   ƒ  sN   € õ =á×ÒÙçƒ{ÙØ€KØ€LðÜÔàˆô 	Öøð ˆô 	Õús   ©
A ÁAc               ó   € V ^8„  d   QhRR/# r+   r   )r/   s   "r#   r0   r0      s   € ÷ +ñ +˜dñ +r"   c                 ór  € \        4        \        P                  4       '       dj   \        \        P	                  4       4       FH  p V P                  4       '       d"   V P
                  P                  R4      '       d   K<  \        V R4       KJ  	   ^ RIp^ RI	pVP                  VP                  4       F@  w  r4pVP                  R4      '       g   VR8X  d   K&   \        P                  ! RV 24       KB  	  R#   \         d"   p\        P!                  RYF4        Rp?Km  Rp?ii ; i  \"         d     R# i ; i)zLThe discovery passes, in precedence order (see :func:`_discover_providers`).r‹   rû   NÚbasez
providers.z.Failed to import legacy provider module %s: %srâ   )r&  Ú_BUNDLED_PLUGINS_DIRrÂ   rä   rå   rD   rx   ræ   ÚpkgutilÚ	providersÚiter_modulesÚ__path__r  Úimport_moduleÚImportErrorr9   r  r8   )rë   r<  Ú_pkgÚ	_importerÚmodnameÚ_ispkgr>   s          r#   r7  r7     sú   € ô  $Ô%ô ×"Ñ"×$Ò$ÜÔ0×8Ñ8Ó:Ö;ˆEØ—<‘<—>’> U§Z¡Z×%:Ñ%:¸:×%FÒ%FÙÜ˜u iÖ0ñ <ðÛã à*1×*>Ñ*>¸t¿}¹}Ö*MÑ&ˆI Ø×!Ñ! #×&Ò&¨'°VÔ*;ÙðÜ×'Ò'¨*°W°IÐ(>Ö?ó	 +Nøô
 ô Ü—‘ØDÀg÷ò ûðûô ô Úðús=   ÂA	D' ÃC8Ã2D' Ã8D$ÄDÄD' ÄD$Ä$D' Ä'D6Ä5D6)FÚ__conditional_annotations__r   Ú
__future__r   rò   r  Úimportlib.utilÚloggingr¹   r5   Ú	threadingr­   Úcontextvarsr   Údataclassesr   r   Úpathlibr   Útypingr   Úproviders.baser   Ú	getLoggerr   r9   r
   r    r   r   r   r   rE   rF   r¯   r   r$   ÚLockrª   r'   Ú__file__ÚresolveÚparentr;  r?   rI   rP   rQ   rR   Úobjectr^   rb   r|   r�   rš   r    rN   rt   ru   r°   rÅ   rÈ   rÞ   r±   r÷   ræ   r&  r  rs   r7  )rF  s   @r#   Ú<module>rV     s·  øðô õD #ã Û Û Û Û 	Û 
Û Û Ý "ß (Ý Ý å *à	×	Ò	˜8Ó	$€ð )+€	Ð%Ó *Ø€ˆ.Ó ð €ˆ.Ó Ø"€�Ó "Ø59Ð Ð2Ó 9Ø€Ø€Ø #Ð ð ÷*ð *ó ð*ð  ')€Ð#Ó (Ø—N’NÓ$Ð ñ
 7AÐA`ÐjnÔ6oÐ Ð3Ó oñ 	ˆƒN×ÑÓ×#Ñ#×*Ñ*¨YÕ6Ð9JÕJð õ
=õ0õ0
#ð( 24Ð Ð.Ó 3Ø)+Ð ˜Ó +Ù"›HÐ õõ*&õR`õ6õ2ð&¨U÷ õðÐY^÷ õ:Rõõõ  õF)õ:Qð
4È÷ 4õndõNõ0÷:+r"   