Ë
    âß²j¸  ã                  óx   — d Z ddlmZ ddlmZ dd„Zdd„Z	 	 	 	 	 	 dd„Z	 	 	 	 	 	 	 	 	 	 dd„Zdd„Z	dd	„Z
dd
„Zy)zFHelpers for reading the effective fallback provider chain from config.é    )Úannotations)ÚAnyc                ód   — t        | t        «      r| j                  «       j                  d«      S dS )Nú/Ú )Ú
isinstanceÚstrÚstripÚrstrip)Úvalues    ú?/home/ubuntu/.hermes/hermes-agent/hermes_cli/fallback_config.pyÚ_normalized_base_urlr      s'   € Ü(2°5¼#Ô(>ˆ5�;‰;‹=×Ñ Ó$ÐFÀBÐFó    c                óP  — t        | t        «      syt        | j                  d«      xs d«      j	                  «       x}r|S t        | j                  d«      xs | j                  d«      xs d«      j	                  «       x}r$ddlm}  ||«      xs dj	                  «       xs dS y)aé  API key for one fallback entry: inline ``api_key``, else ``key_env``.

    Mirrors the custom-provider convention (``api_key_env`` accepted as alias); None when neither
    yields a value so ``resolve_runtime_provider`` falls through to standard credential resolution.
    ``key_env`` goes through ``agent.secret_scope.get_secret``, not raw ``os.getenv``: in a
    multiplexed gateway a bare env read ignores the active profile's scope and can return another
    profile's credential.
    NÚapi_keyr   Úkey_envÚapi_key_envr   )Ú
get_secret)r   Údictr	   Úgetr
   Úagent.secret_scoper   )ÚentryÚinliner   r   s       r   Úresolve_entry_api_keyr      s–   € ô �eœTÔ"ØÜ�U—Y‘Y˜yÓ)Ò/¨RÓ0×6Ñ6Ó8Ð8€vÐ8ØˆÜ�e—i‘i 	Ó*ÒL¨e¯i©i¸Ó.FÒLÈ"ÓM×SÑSÓUÐU€wÐUÝ1Ù˜7Ó#Ò) r×0Ñ0Ó2Ò:°dÐ:Ør   c                óH  — |xs i }t        |j                  d«      xs d«      j                  «       }|j                  «       dk7  r|S t        |j                  d«      xs | xs i j                  d«      xs d«      j                  «       }|r|j                  «       dk7  r|S |S )u8  Provider identity to persist/display for a resolved fallback entry.

    ``resolve_runtime_provider`` returns the bare billing class ``"custom"``
    for every named ``providers:`` / ``custom_providers:`` entry; the entry's
    configured id only survives in ``requested_provider``. Fallback resolvers
    that persist ``runtime["provider"]`` as the agent identity therefore label
    sessions/billing rows ``custom`` instead of the configured provider name â€”
    while the manual ``/model`` switch path correctly persists the named id
    (#98739). Same class as the delegation fix in ``tools/delegate_tool.py``.

    Returns the entry's requested identity when the resolved provider is the
    bare ``custom`` class; a genuinely ad-hoc endpoint (requested provider IS
    ``custom``) keeps the bare class unchanged.
    Úproviderr   ÚcustomÚrequested_provider)r	   r   r
   Úlower)r   ÚruntimeÚresolvedÚ	requesteds       r   Úeffective_runtime_providerr#      s¢   € ð" Šm˜€GÜ�7—;‘;˜zÓ*Ò0¨bÓ1×7Ñ7Ó9€HØ‡~�~Ó˜8Ò#ØˆÜØ�‰Ð(Ó)ò 	ØŠK�R×Ñ˜ZÓ(ò	àó÷ �eƒgð	 ñ
 �Y—_‘_Ó&¨(Ò2ØÐØ€Or   c                óŒ   — dj                  d„ | |fD «       «      xs d}dj                  d„ ||fD «       «      xs d}d|› d|› d�S )	a   User-visible one-shot line for a provider switch made during credential resolution, before
    any AIAgent exists (#74349). Shared by the messaging gateway, the TUI/Desktop gateway and cron
    so the three pre-agent fallback paths cannot drift in wording.r   c              3  óT   K  — | ]   }|sŒt        |«      j                  «       –— Œ" y ­w©N©r	   r
   ©Ú.0Úps     r   ú	<genexpr>z,pre_agent_fallback_notice.<locals>.<genexpr>D   s   è ø€ Ò[¨qÒYZœC ›FŸL™LŸNÑ[ùó   ‚(Š(Úprimaryc              3  óT   K  — | ]   }|sŒt        |«      j                  «       –— Œ" y ­wr&   r'   r(   s     r   r+   z,pre_agent_fallback_notice.<locals>.<genexpr>E   s   è ø€ Ò^°Ò\]œS ›VŸ\™\Ÿ^Ñ^ùr,   Úfallbacku   âš ï¸� Provider fallback: z unavailable; using z for this response.)Újoin)Úprimary_providerÚprimary_modelÚfallback_providerÚfallback_modelÚprimary_descÚfallback_descs         r   Úpre_agent_fallback_noticer7   >   s[   € ð —8‘8Ñ[Ð5EÀ}Ð4UÔ[Ó[ÒhÐ_h€LØ—H‘HÑ^Ð6GÈÐ5XÔ^Ó^ÒlÐbl€MØ'¨ ~Ð5IÈ-ÈÐXkÐlÐlr   c                ó¸  — t        | t        «      r| gnt        | t        «      r| ng }g }|D ]«  }t        |t        «      sŒt        |j	                  d«      xs d«      j                  «       }t        |j	                  d«      xs d«      j                  «       }|r|sŒqi |¥||dœ¥}t        |j	                  d«      «      }|r||d<   |j                  |«       Œ­ |S )Nr   r   Úmodel)r   r9   Úbase_url)r   r   Úlistr	   r   r
   r   Úappend)ÚrawÚ
candidatesÚentriesr   r   r9   Ú
normalizedr:   s           r   Ú_iter_fallback_entriesrA   J   sÏ   € Ü$ S¬$Ô/�#‘¼JÀsÌDÔ<Q±SÐWY€JØ$&€GØò #ˆÜ˜%¤Ô&ØÜ�u—y‘y Ó,Ò2°Ó3×9Ñ9Ó;ˆÜ�E—I‘I˜gÓ&Ò,¨"Ó-×3Ñ3Ó5ˆÙ™uØØD˜ÐD¨8¸eÒDˆ
Ü'¨¯	©	°*Ó(=Ó>ˆÙØ%-ˆJ�zÑ"Ø�‰�zÕ"ð#ð €Nr   c                ó8  — t        | j                  d«      xs d«      j                  «       j                  «       t        | j                  d«      xs d«      j                  «       j                  «       t	        | j                  d«      «      j                  «       fS )Nr   r   r9   r:   )r	   r   r
   r   r   )r   s    r   Ú_entry_identityrC   \   sv   € äˆE�I‰I�jÓ!Ò' RÓ(×.Ñ.Ó0×6Ñ6Ó8ÜˆE�I‰I�gÓÒ$ "Ó%×+Ñ+Ó-×3Ñ3Ó5Ü˜UŸY™Y zÓ2Ó3×9Ñ9Ó;ðð r   c                óÚ   — | xs i } g }t        «       }dD ]S  }t        | j                  |«      «      D ]4  }t        |«      }||vsŒ|j	                  |«       |j                  |«       Œ6 ŒU |S )an  Return the effective fallback chain merged across old and new config keys.

    ``fallback_providers`` remains the primary source of truth and keeps its order. Legacy
    ``fallback_model`` entries are appended afterwards unless they target the same
    provider/model/base_url route as an earlier entry. The returned list always contains fresh dict
    copies.
    )Úfallback_providersr4   )ÚsetrA   r   rC   Úaddr<   )ÚconfigÚchainÚseenÚkeyr   Úidentitys         r   Úget_fallback_chainrM   d   su   € ð Š\�r€FØ"$€EÜ&)£e€DØ7ò $ˆÜ+¨F¯J©J°s«OÓ<ò 	$ˆEÜ& uÓ-ˆHØ˜tÒ#Ø—‘˜Ô"Ø—‘˜UÕ#ñ		$ð$ð €Lr   N)r   r   Úreturnr	   )r   údict[str, Any] | NonerN   z
str | None)r   rO   r    rO   rN   r	   )
r1   r   r2   r   r3   r   r4   r   rN   r	   )r=   r   rN   úlist[dict[str, Any]])r   zdict[str, Any]rN   ztuple[str, str, str])rH   rO   rN   rP   )Ú__doc__Ú
__future__r   Útypingr   r   r   r#   r7   rA   rC   rM   © r   r   ú<module>rU      sx   ðÙ Lå "å óGóð&Ø ðØ+@ðàóð>mØðmØ*-ðmØBEðmØWZðmàómóó$ôr   