§
    øžyj‘  ã                  ó,  — U d Z ddlmZ ddl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  ej        e¦  «        Zi Zded<   i Zded	<   dad
ed<   da ee¦  «                             ¦   «         j        j        dz  dz  Zd!d„Zd"d„Zd#d„Zd$d„Zd%d„Zd&d „ZdS )'uÇ  Provider module registry.

Provider profiles can live in two places:

1. Bundled plugins: ``plugins/model-providers/<name>/`` (shipped with hermes-agent)
2. User plugins: ``$HERMES_HOME/plugins/model-providers/<name>/``

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()`` scans both locations and imports every plugin. User
plugins override bundled plugins on name collision (last-writer-wins), 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)ÚPath)ÚOMIT_TEMPERATUREÚProviderProfilezdict[str, ProviderProfile]Ú	_REGISTRYzdict[str, str]Ú_ALIASESzlist[ProviderProfile] | NoneÚ_PROVIDER_LIST_CACHEFÚpluginsúmodel-providersÚprofiler   ÚreturnÚNonec                óZ   — | t           | j        <   | j        D ]}| j        t          |<   ŒdadS )uû   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.
    N)r   ÚnameÚaliasesr   r	   )r   Úaliass     ú8/home/ragecks/.hermes/hermes-agent/providers/__init__.pyÚregister_providerr   6   s:   € ð &…IˆgŒlÑØ”ð 'ð 'ˆØ!œ,��‰ˆØÐÐÐó    r   ÚstrúProviderProfile | Nonec                ó–   — t           st          ¦   «          t                               | | ¦  «        }t                               |¦  «        S )z{Look up a provider profile by name or alias.

    Returns None if the provider has no profile (falls back to generic).
    )Ú_discoveredÚ_discover_providersr   Úgetr   )r   Ú	canonicals     r   Úget_provider_profiler   D   s=   € õ
 ð ÝÑÔÐÝ—’˜T 4Ñ(Ô(€IÝ�=Š=˜Ñ#Ô#Ð#r   úlist[ProviderProfile]c                 óV  — t           st          ¦   «          t          �t          t          ¦  «        S t	          ¦   «         } g }t
                               ¦   «         D ]?}t          |¦  «        }|| vr*|                      |¦  «         | 	                    |¦  «         Œ@|at          |¦  «        S )zAReturn all registered provider profiles (one per canonical name).)
r   r   r	   ÚlistÚsetr   ÚvaluesÚidÚaddÚappend)ÚseenÚresultr   Úpids       r   Úlist_providersr)   O   sž   € õ ð ÝÑÔÐÝÐ'ÝÕ(Ñ)Ô)Ð)å‘U”U€DØ$&€FÝ×#Ò#Ñ%Ô%ð #ð #ˆÝ�‰kŒkˆØ�dˆ?ˆ?Ø�HŠH�S‰MŒMˆMØ�MŠM˜'Ñ"Ô"Ð"øØ!ÐÝ�‰<Œ<Ðr   úPath | Nonec                 ó‚   — 	 ddl m}   | ¦   «         dz  dz  }|                     ¦   «         r|ndS # t          $ r Y dS w xY w)z>Return ``$HERMES_HOME/plugins/model-providers/`` if it exists.r   )Úget_hermes_homer
   r   N)Úhermes_constantsr,   Úis_dirÚ	Exception)r,   Úds     r   Ú_user_plugins_dirr1   b   sj   € ðØ4Ð4Ð4Ð4Ð4Ð4àˆOÑÔ 	Ñ)Ð,=Ñ=ˆØ—H’H‘J”JÐ(ˆqˆq DÐ(øÝð ð ð Øˆtˆtðøøøs   ‚-0 °
>½>Ú
plugin_dirr   Úsourcec                óp  — | dz  }|                      ¦   «         sdS | j                             dd¦  «        }|dk    rd|› �}nd|› �}|t          j        v rdS 	 t
          j                             ||t          | ¦  «        g¬¦  «        }|�|j	        €dS t
          j         
                    |¦  «        }|t          j        |<   |j	                             |¦  «         dS # t          $ rM}t                               d	|| j        |¦  «         t          j                             |d¦  «         Y d}~dS d}~ww xY w)
zImport a single plugin directory so it self-registers.

    ``source`` is "bundled" or "user", used only for log messages.
    z__init__.pyNú-Ú_Úbundledzplugins.model_providers.Ú_hermes_user_provider_)Úsubmodule_search_locationsz(Failed to load %s provider plugin %s: %s)Úexistsr   ÚreplaceÚsysÚmodulesÚ	importlibÚutilÚspec_from_file_locationr   ÚloaderÚmodule_from_specÚexec_moduler/   ÚloggerÚwarningÚpop)r2   r3   Ú	init_fileÚ	safe_nameÚmodule_nameÚspecÚmoduleÚexcs           r   Ú_import_plugin_dirrM   m   se  € ð
 ˜]Ñ*€IØ×ÒÑÔð Øˆð ”×'Ò'¨¨SÑ1Ô1€IØ�ÒÐØ<°Ð<Ð<ˆˆà:¨yÐ:Ð:ˆà•c”kÐ!Ð!Øˆð+ÝŒ~×5Ò5Ø˜ÅÀJÁÄÐ?Pð 6ñ 
ô 
ˆð ˆ<˜4œ;Ð.ØˆFÝ”×0Ò0°Ñ6Ô6ˆØ#)�Œ�KÑ ØŒ×Ò Ñ'Ô'Ð'Ð'Ð'øÝð +ð +ð +Ý�ŠØ6¸À
ÄÐQTñ	
ô 	
ð 	
õ 	Œ�Š˜ TÑ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*Ð*øøøøð	+øøøs    Á9C ÂAC Ã
D5Ã(AD0Ä0D5c                 óH  — t           rdS da t                               ¦   «         rht          t                               ¦   «         ¦  «        D ]A} |                      ¦   «         r| j                             d¦  «        rŒ1t          | d¦  «         ŒBt          ¦   «         }|�ct          |                     ¦   «         ¦  «        D ]A} |                      ¦   «         r| j                             d¦  «        rŒ1t          | d¦  «         ŒB	 ddl	}ddl
}|                     |j        ¦  «        D ]m\  }}}|                     d¦  «        s|dk    rŒ"	 t          j        d	|› �¦  «         Œ;# t          $ r&}t                                d
||¦  «         Y d}~Œfd}~ww xY wdS # t$          $ r Y dS w xY w)a¤  Populate the registry by importing every provider plugin.

    Order:
      1. Bundled plugins at ``<repo>/plugins/model-providers/<name>/``
      2. User plugins at ``$HERMES_HOME/plugins/model-providers/<name>/``
      3. 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.
    NT)r6   ú.r7   Úuserr   r6   Úbasez
providers.z.Failed to import legacy provider module %s: %s)r   Ú_BUNDLED_PLUGINS_DIRr.   ÚsortedÚiterdirr   Ú
startswithrM   r1   ÚpkgutilÚ	providersÚiter_modulesÚ__path__r>   Úimport_moduleÚImportErrorrD   rE   r/   )ÚchildÚuser_dirrV   Ú_pkgÚ	_importerÚmodnameÚ_ispkgrL   s           r   r   r   “   s  € õ ð ØˆØ€Kõ ×"Ò"Ñ$Ô$ð 1ÝÕ0×8Ò8Ñ:Ô:Ñ;Ô;ð 	1ð 	1ˆEØ—<’<‘>”>ð  U¤Z×%:Ò%:¸:Ñ%FÔ%Fð ØÝ˜u iÑ0Ô0Ð0Ð0õ
 !Ñ"Ô"€HØÐÝ˜H×,Ò,Ñ.Ô.Ñ/Ô/ð 	.ð 	.ˆEØ—<’<‘>”>ð  U¤Z×%:Ò%:¸:Ñ%FÔ%Fð ØÝ˜u fÑ-Ô-Ð-Ð-ð
Øˆˆˆà Ð Ð Ð à*1×*>Ò*>¸t¼}Ñ*MÔ*Mð 	ð 	Ñ&ˆI�w Ø×!Ò! #Ñ&Ô&ð ¨'°VÒ*;Ð*;ØðÝÔ'Ð(>°WÐ(>Ð(>Ñ?Ô?Ð?Ð?øÝð ð ð Ý—’ØDÀgÈsñô ð ð ð ð ð ð øøøøðøøøð	ð 	øõ ð ð ð Øˆˆðøøøs=   ÄAF ÅEÅF Å
FÅ(F	ÆF Æ	FÆF Æ
F!Æ F!)r   r   r   r   )r   r   r   r   )r   r   )r   r*   )r2   r   r3   r   r   r   )r   r   )Ú__doc__Ú
__future__r   r>   Úimportlib.utilÚloggingr<   Úpathlibr   Úproviders.baser   r   Ú	getLoggerÚ__name__rD   r   Ú__annotations__r   r	   r   Ú__file__ÚresolveÚparentrR   r   r   r)   r1   rM   r   © r   r   ú<module>ro      sy  ððð ð ð< #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ø Ð Ð Ð Ø €€€Ø 
€
€
€
Ø Ð Ð Ð Ð Ð à <Ð <Ð <Ð <Ð <Ð <Ð <Ð <à	ˆÔ	˜8Ñ	$Ô	$€à(*€	Ð *Ð *Ð *Ñ *Ø€Ð Ð Ð Ñ Ø59Ð Ð 9Ð 9Ð 9Ñ 9Ø€ð 	€Dˆ�N„N×ÒÑÔÔ#Ô*¨YÑ6Ð9JÑJð ð
 ð  ð  ð  ð$ð $ð $ð $ðð ð ð ð&ð ð ð ð#+ð #+ð #+ð #+ðL3ð 3ð 3ð 3ð 3ð 3r   