Ë
    áß²jü"  ã                  óÎ   — d Z ddlmZ ddlZddlZddlmZmZmZm	Z	m
Z
mZmZmZ ddlmZ  ed«      Zdd„Z G d„ d	e
e   «      Zej&                  d
dœ	 	 	 	 	 	 	 	 	 	 	 dd„Zdd„Zy)a�  Shared engine behind the ``agent.*_registry`` provider registries.

Every pluggable-backend registry has the same shape: a global name->provider map
plus per-profile *scoped* maps (multiplexed gateways), a lock, registration with
re-registration logging, and the snapshot/restore pair :mod:`hermes_cli.plugins`
uses to unwind a plugin. Each ``*_registry`` module instantiates one
:class:`ProviderRegistry` and re-exports its bound methods under the historical
module-level names via :meth:`ProviderRegistry.export`, so ``patch("agent.x_registry.get_provider")``
targets and the ``_providers`` / ``_scoped_providers`` / ``_lock`` test hooks are unchanged.
é    )ÚannotationsN)ÚAnyÚCallableÚDictÚ	FrozenSetÚGenericÚListÚOptionalÚTypeVar)Úhermes_home_keyÚPc                ó>   — | j                  «       j                  «       S ©N)ÚstripÚlower©Únames    ú</home/ubuntu/.hermes/hermes-agent/agent/provider_registry.pyÚ	lower_keyr      s   € Ø�:‰:‹<×ÑÓÐó    c                  óê   — e Zd ZdZej
                   e«       ddœ	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Zdd„Zdd„Z	ddœdd„Z
ddd	„Zddœdd
„Zddœdd„Zddœdd„Zddœdd„Zddœ	 	 	 	 	 	 	 	 	 dd„Zdd„Zdd„Zy)ÚProviderRegistryaÄ  Global + per-scope provider map with plugin snapshot/restore support.

    ``normalize`` is ``str.strip`` or ``lower_key`` (case-insensitive registries mirror
    how their dispatcher normalizes the configured name). ``builtin_names`` are reserved
    for in-tree implementations; a collision calls ``on_builtin_collision(key)`` and, if
    that returns, skips registration. ``logger`` is the owning module's so record names
    stay per-registry.
    N)Ú	normalizeÚbuiltin_namesÚon_builtin_collisionc               ó.  — || _         || _        || _        || _        || _        || _        i | _        i | _        d| _        i | _	        t        j                  «       | _        |j                  «       r|| _        y |d   j                  «       |dd  z   | _        y )Nr   é   )ÚlabelÚprovider_clsÚloggerr   r   Ú_on_builtin_collisionÚ
_providersÚ_scoped_providersÚ_generationÚ_scoped_generationsÚ	threadingÚLockÚ_lockÚisupperr   Ú
_log_label)Úselfr   r   r    r   r   r   s          r   Ú__init__zProviderRegistry.__init__%   s‹   € ð
 ˆŒ
Ø(ˆÔØˆŒØ"ˆŒØ*ˆÔØ%9ˆÔ"Ø(*ˆŒØ:<ˆÔØˆÔØ35ˆÔ Ü—^‘^Ó%ˆŒ
à#(§=¡=¤?˜%ˆ�¸¸a¹¿¹Ó8HÈ5ÐQRÐQSÈ9Ñ8Tˆ�r   c               ó’   — |€| j                   S |r| j                  j                  |i «      S | j                  j                  |i «      S r   )r"   r#   Ú
setdefaultÚget)r+   ÚscopeÚcreates      r   Ú_targetzProviderRegistry._target8   sF   € Øˆ=Ø—?‘?Ð"ÙØ×)Ñ)×4Ñ4°U¸BÓ?Ð?Ø×%Ñ%×)Ñ)¨%°Ó4Ð4r   c                óŒ   — |€| xj                   dz  c_         y | j                  j                  |d«      dz   | j                  |<   y )Nr   r   )r$   r%   r/   ©r+   r0   s     r   Ú_bumpzProviderRegistry._bump?   sB   € Øˆ=Ø×Ò Ñ!Öà.2×.FÑ.F×.JÑ.JÈ5ÐRSÓ.TÐWXÑ.XˆD×$Ñ$ UÒ+r   )r0   c          
     ó˜  — t        || j                  «      sZ| j                  j                  d   dv rdnd}t        d|› d| j                  j                  › dt	        |«      j                  › �«      ‚t        |d«      }t        |t        «      r|j                  «       st        | j                  › d	�«      ‚| j                  |«      }|| j                  v r| j                  �| j                  |«       y
| j                  5  | j                  |d¬«      }|j                  |«      }|||<   | j!                  |«       d
d
d
«       �>| j"                  j%                  | j                  › d�|t	        |«      j                  «       y
| j"                  j%                  d| j&                  › d�|t	        |«      j                  «       y
# 1 sw Y   ŒˆxY w)zGRegister a provider; same-name re-registration overwrites (hot reload).r   ÚAEIOUÚanÚazregister_provider() expects ú z instance, got r   z* provider .name must be a non-empty stringNT©r1   z% provider '%s' re-registered (was %r)zRegistered z provider '%s' (%s))Ú
isinstancer   Ú__name__Ú	TypeErrorÚtypeÚgetattrÚstrr   Ú
ValueErrorr   r   r   r!   r(   r2   r/   r5   r    Údebugr*   )r+   Úproviderr0   ÚarticleÚraw_nameÚkeyÚtargetÚexistings           r   ÚregisterzProviderRegistry.registerE   s   € ä˜( D×$5Ñ$5Ô6Ø"×/Ñ/×8Ñ8¸Ñ;¸wÑF‘dÈCˆGÜØ.¨w¨i°q¸×9JÑ9J×9SÑ9SÐ8Tð U!Ü!% h£×!8Ñ!8Ð 9ð;óð ô ˜8 VÓ,ˆÜ˜(¤CÔ(°·±Ô0@Ü §
¡
˜|Ð+UÐVÓWÐWØ�n‰n˜XÓ&ˆØ�$×$Ñ$Ñ$Ø×)Ñ)Ð5Ø×*Ñ*¨3Ô/ØØ�Z‰Zñ 	Ø—\‘\ %°�\Ó5ˆFØ—z‘z #“ˆHØ"ˆF�3‰KØ�J‰J�uÔ÷		ð
 ÐØ�K‰K×ÑØ—:‘:�,ÐCÐDÀcÌ4ÐPXË>×KbÑKbõð �K‰K×ÑØ˜dŸo™oÐ.Ð.AÐBÀCÌÈhË×I`ÑI`õ÷	ð 	ús   Ã>;G Ç G	c                óâ   — | j                   5  t        | j                  «      }|j                  | j                  j                  |xs
 t        «       i «      «       ddd«       |S # 1 sw Y   S xY w)zBGlobal map overlaid with the active profile's scoped map (a copy).N)r(   Údictr"   Úupdater#   r/   r   )r+   r0   Úmergeds      r   rN   zProviderRegistry.mergedc   s`   € à�Z‰Zñ 	VÜ˜$Ÿ/™/Ó*ˆFØ�M‰M˜$×0Ñ0×4Ñ4°UÒ5O¼oÓ>OÐQSÓTÔU÷	Vð ˆ÷	Vð ˆús   �AA$Á$A.c               óX   — t        | j                  |«      j                  «       d„ ¬«      S )z0Return all registered providers, sorted by name.c                ó   — | j                   S r   r   )Úps    r   ú<lambda>z1ProviderRegistry.list_providers.<locals>.<lambda>l   s
   € ÀÇÁ€ r   )rG   )ÚsortedrN   Úvaluesr4   s     r   Úlist_providerszProviderRegistry.list_providersj   s"   € ä�d—k‘k %Ó(×/Ñ/Ó1Ñ7GÔHÐHr   c               ó4  — t        |t        «      sy| j                  |«      }| j                  5  | j                  j                  |xs
 t        «       i «      j                  |«      xs | j                  j                  |«      	 cddd«       S # 1 sw Y   yxY w)zDReturn the provider registered under *name* (scoped first), or None.N)r<   rA   r   r(   r#   r/   r   r"   )r+   r   r0   rG   s       r   Úget_providerzProviderRegistry.get_providern   s~   € ä˜$¤Ô$ØØ�n‰n˜TÓ"ˆØ�Z‰Zñ 	à×&Ñ&×*Ñ*¨5Ò+E´OÓ4EÀrÓJ×NÑNÈsÓSò ,Ø—?‘?×&Ñ& sÓ+ð÷	÷ 	ò 	ús   ¯ABÂBc               ó²   — |xs
 t        «       }| j                  5  | j                  | j                  j	                  |d«      fcddd«       S # 1 sw Y   yxY w)z=Cache fingerprint ``(global_generation, scoped_generation)``.r   N)r   r(   r$   r%   r/   )r+   r0   Úactive_scopes      r   Úregistry_generationz$ProviderRegistry.registry_generationy   sQ   € àÒ1¤Ó 1ˆØ�Z‰Zñ 	SØ×#Ñ# T×%=Ñ%=×%AÑ%AÀ,ÐPQÓ%RÐR÷	S÷ 	Sò 	Sús   ›(AÁAc               ó¨   — | j                   5  | j                  |d¬«      j                  | j                  |«      «      cddd«       S # 1 sw Y   yxY w)zGExact-slot lookup (no global fallback) used to detect plugin ownership.Fr;   N)r(   r2   r/   r   )r+   r   r0   s      r   Úsnapshot_registrationz&ProviderRegistry.snapshot_registration   sF   € à�Z‰Zñ 	OØ—<‘< ¨e�<Ó4×8Ñ8¸¿¹ÈÓ9MÓN÷	O÷ 	Oò 	Oús   �1AÁAc               ó^  — | j                  |«      }| j                  5  | j                  |d¬«      }|j                  |«      |ur
	 ddd«       y|€|j	                  |d«       n|||<   | j                  |«       |�|s| j                  j	                  |d«       ddd«       y# 1 sw Y   yxY w)zGRestore *previous* only when *current* is still installed under *name*.Tr;   NF)r   r(   r2   r/   Úpopr5   r#   )r+   r   ÚcurrentÚpreviousr0   rG   rH   s          r   Úrestore_registrationz%ProviderRegistry.restore_registration„   s«   € ð �n‰n˜TÓ"ˆØ�Z‰Zñ 
	8Ø—\‘\ %°�\Ó5ˆFØ�z‰z˜#‹ gÑ-Ø÷
	8ð 
	8ð ÐØ—
‘
˜3 Õ%à&��s‘Ø�J‰J�uÔØÐ ©Ø×&Ñ&×*Ñ*¨5°$Ô7÷
	8ð ÷
	8ð ús   ž(B#ÁAB#Â#B,c                ó  — | j                   5  | j                  j                  «        | j                  j                  «        | j                  j                  «        | xj
                  dz  c_        ddd«       y# 1 sw Y   yxY w)z(Clear every registration. **Test-only.**r   N)r(   r"   Úclearr#   r%   r$   )r+   s    r   Úreset_for_testsz ProviderRegistry.reset_for_tests–   sc   € à�Z‰Zñ 	"Ø�O‰O×!Ñ!Ô#Ø×"Ñ"×(Ñ(Ô*Ø×$Ñ$×*Ñ*Ô,Ø×Ò Ñ!Õ÷		"÷ 	"ñ 	"ús   �A$A:Á:Bc                ó  — |j                  | j                  | j                  | j                  | j                  | j
                  | j                  | j                  | j                  | j                  | j                  ¬«
       y)z“Bind the historical module-level API (+ ``_providers``/``_scoped_providers``/
        ``_lock`` test hooks) into a ``*_registry`` module namespace.)
r"   r#   r(   Úregister_providerrU   rW   r\   ra   rZ   Ú_reset_for_testsN)rM   r"   r#   r(   rJ   rU   rW   r\   ra   rZ   rd   )r+   Ú	namespaces     r   ÚexportzProviderRegistry.exportž   si   € ð 	×ÑØ—‘¸$×:PÑ:PÐX\×XbÑXbØ"Ÿm™m¸D×<OÑ<OØ×*Ñ*À$×B\ÑB\Ø!%×!:Ñ!:Ø $× 8Ñ 8È4×K_ÑK_ð 	õ 	
r   )r   rA   r   r?   r    úlogging.Loggerr   zCallable[[str], str]r   zFrozenSet[str]r   zOptional[Callable[[str], None]]ÚreturnÚNone)r0   úOptional[str]r1   Úboolrk   úDict[str, P])r0   rm   rk   rl   )rD   r   r0   rm   rk   rl   r   )r0   rm   rk   ro   )r0   rm   rk   zList[P])r   rA   r0   rm   rk   úOptional[P])r0   rm   rk   Útuple)
r   rA   r_   r   r`   rp   r0   rm   rk   rn   )rk   rl   )rh   zDict[str, Any]rk   rl   )r=   Ú
__module__Ú__qualname__Ú__doc__rA   r   Ú	frozensetr,   r2   r5   rJ   rN   rU   rW   rZ   r\   ra   rd   ri   © r   r   r   r      së   „ ñð +.¯)©)ÑU^ÓU`Ø@DñUØðUØ+/ðUØ9GðUà'ðUàDRðUð >ðUð 
ó	Uó&5óYð ?Cõ ô<ð 8<õ Ið AEõ 	ð =Aõ Sð JNõ Oð W[ñØðØ"#ðØ/:ðØFSðà	óó$"ô	
r   r   F)ÚlevelÚexc_infoc               ó¢   — 	 t        | j                  «       «      S # t        $ r*}|j                  ||| j                  ||¬«       Y d}~yd}~ww xY w)zP``bool(provider.is_available())`` that treats a raising provider as unavailable.)rx   NF)rn   Úis_availableÚ	ExceptionÚlogr   )rD   r    Úfmtrw   rx   Úexcs         r   Úis_available_safer   ª   sH   € ðÜ�H×)Ñ)Ó+Ó,Ð,øÜò Ø�
‰
�5˜#˜xŸ}™}¨c¸Hˆ
ÔEÜûðús   ‚ ›	A¤ A	Á	Ac                óÄ  — d}	 ddl m}  |«       }t        |t        «      r|j	                  | «      nd}t        |t        «      r|j	                  d«      nd}t        |t
        «      r |j                  «       r|j                  «       }|r	 ddl	m
} |j                  «       |k(  rd}|S |S # t        $ r}|j                  d| |«       Y d}~ŒCd}~ww xY w# t        $ r Y |S w xY w)z•Read ``<section>.provider`` from config.yaml, mapping the managed Nous
    selection to ``fal`` (the FAL plugin services it via the managed gateway).Nr   )Úload_config_readonlyrD   z*Could not read %s.provider from config: %s)ÚNOUS_MANAGED_PROVIDERÚfal)Úhermes_cli.configr�   r<   rL   r/   rA   r   r{   rC   Útools.tool_backend_helpersr‚   r   )	Úsectionr    Ú
configuredr�   ÚcfgÚblockÚrawr~   r‚   s	            r   Úconfigured_provider_namer‹   µ   sÛ   € ð !%€JðQÝ:Ù"Ó$ˆÜ$.¨s´DÔ$9�—‘˜Ô ¸tˆÜ'1°%¼Ô'>ˆe�i‰i˜
Ô#ÀDˆÜ�cœ3Ô C§I¡I¤KØŸ™›ˆJñ ð	ÝHØ×ÑÓ!Ð%:Ò:Ø"�
ð Ðˆ:Ðøô ò QØ�‰ÐAÀ7ÈC×PÑPûðQûô ò 	ØØÐð	ús*   „BB) Â
C Â)	CÂ2C
Ã
CÃ	CÃC)r   rA   rk   rA   )rD   r   r    rj   r}   rA   rw   Úintrx   rn   rk   rn   )r†   rA   r    rj   rk   rm   )rt   Ú
__future__r   Úloggingr&   Útypingr   r   r   r   r   r	   r
   r   Úhermes_constantsr   r   r   r   ÚDEBUGr   r‹   rv   r   r   ú<module>r’      sŠ   ðñ	õ #ã Û ß S× SÓ Så ,áˆCƒL€ó ôL
�w˜q‘zô L
ð` FMÇ]Á]ÐejñØðØ)ðØ03ðØ?BðØ^bðà	óôr   