+
    „WÝjˆ† ã                  óÈ  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
Ht ^ RIHtHtHt ^ RIHtHtHtHtHtHtHtHtHt ^ RIHt ^ RIHtHtHtH t H!t! ^ R	I"H#t#H$t$H%t%H&t& ^ R
I'H(t( ]PR                  ! ]*4      t+R R lt,R R lt-R R lt.RüR R llt/R R lt0Rt1]Pd                  ! R]Pf                  4      t4Rýt5R]6R&   R R lt7R R lt8R R lt9 ! R R ]4      t:/ R!]:! R"R#4      bR$]:! R"R%4      bR&]:! R"R'4      bR(]:! R"R(4      bR)]:! R*R+4      bR,]:! R*R,4      bR-]:! R*R-4      bR.]:! R*R.4      bR/]:! R*R/4      bR0]:! R1R04      bR2]:! R2R34      bR4]:! R5R44      bR6]:! R7R64      bR8]:! R8R84      bR9]:! R9R94      bR:]:! R;R:4      bR<]:! R=R<4      bR>]:! R?R>4      R@]:! RAR@4      RB]:! RCRB4      RD]:! RERD4      /Ct;RF]6RG&    ! RH RI]4      t</ t=RJ]6RK&   RL RM lt>/ t?RJ]6RN&   RþRO RP llt@RsARQ]6RR&   RsBRS]6RT&   RU RV ltCRW RX ltDRY RZ ltER[ R\ ltF]G! 0 Rÿm4      tHR] R^ ltI ! R_ R`]4      tJRaRbRcRbRdRReRRfR/Rg Rh lltK]
 ! Ri Rj4      4       tL]
! RkRl7       ! Rm Rn4      4       tMRoRpRqRrRsRtRuRv/tNRwRaRxRy/tORz R{ ltPER R| R} lltQR~tRRtSR€tT]RR�]SR‚]TRƒ/tU]
! RkRl7       ! R„ R…4      4       tVR† R‡ ltWRˆ R‰ ltXERRŠ R‹ lltYRŒ R� ltZRŽ R� lt[ ! R� R‘]\4      t]R’ R“ lt^ERR” R• llt_ERR– R— llt`R˜ R™ ltaRš R› ltbERRœ R� lltcERRž RŸ lltdERR  R¡ llteR¢ R£ ltfR¤ R¥ ltgR¦ R§ lthR¨ R© ltiRª R« ltjR¬ R­ ltkR® R¯ ltlR° R± ltmR² R³ ltnR´ Rµ ltoR¶ R· ltpR¸ R¹ ltqRº R» ltrR¼ R½ ltsR¾ R¿ lttRÀ RÁ ltu]
 ! RÂ RÃ4      4       tvRÄ RÅ ltwRÆ RÇ ltxRÈ RÉ ltyRÊ RË ltzRÌ RÍ lt{RÎ RÏ lt|RÐ RÑ lt}RÒ RÓ lt~RÔ RÕ ltRÖ R× lt€RØ RÙ lt�RÚ RÛ lt‚RÜ RÝ ltƒRÞ Rß lt„Rà Rá lt…Râ Rã lt†Rä Rå lt‡/ ]ˆEP                  ER]…4      C]ˆEP                  ER]†4      C]ˆEP                  ER]‡4      CtŠRæ]6Rç&   ER	Rè Ré llt‹Rê Rë ltŒER
Rì Rí llt�Rî Rï ltŽRð Rñ lt�Rò Ró lt�Rô Rõ lt‘RþRö R÷ llt’Rø Rù lt“Rú Rû lt”R# (  a`  Shared model-switching logic for the CLI and gateway /model commands.

Pipeline: parse flags -> alias resolution -> provider resolution -> credential resolution ->
normalize model name -> metadata lookup -> build result. Provider switching uses ``--provider``
exclusively; colons are reserved for OpenRouter variant suffixes (``:free``, ``:extended``).)ÚannotationsN)Úsuppress)Ú	dataclassÚfield)ÚAnyÚ
NamedTupleÚOptional)	ÚLLAMACPP_ALIASESÚProviderDefÚcustom_provider_aliasesÚdetermine_api_modeÚ	get_labelÚhost_mandated_api_modeÚis_aggregatorÚnormalize_providerÚresolve_provider_full)Únormalize_model_for_provider)ÚModelCapabilitiesÚ	ModelInfoÚget_model_capabilitiesÚget_model_infoÚlist_provider_models)Úbase_url_host_matchesÚbase_url_hostnameÚbase_url_originÚfile_signature)Úlist_authenticated_providersc               ó    € V ^8„  d   QhRRRR/# )é   Úvaluer   Úreturnú	list[str]© )Úformats   "ÚKC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\model_switch.pyÚ__annotate__r%      s   € ÷ ñ ˜sð  yñ ó    c                óæ  € \        V \        4      '       d   V .pMH\        V \        4      '       d   R V  4       pM(\        V \        \        34      '       d   R V  4       pM. # . p\        4       pV F|  p\        V\        4      '       g   K  VP                  4       pV'       g   K5  VP                  4       V9  g   KL  VP                  VP                  4       4       VP                  V4       K~  	  V# )zaConfigured model IDs from ``{"id": {...}}``, ``["a", "b"]``, ``[{"id"|"name": ...}]`` or ``"a"``.c              3  ó6   "  € T F  qR9  g   K  Vx € K  	  R# 5i)Ú__explicit_model_allowlist__N)r)   Ú__discovered_model_catalog__r"   )Ú.0Úks   & r$   Ú	<genexpr>Ú&_declared_model_ids.<locals>.<genexpr>$   s   é € Ðt¡˜AÐ3sÑ*s—a’a£ùó   ‚�
c              3  óh   "  € T F(  p\        V\        4      '       d   \        V4      MTx € K*  	  R # 5i©N)Ú
isinstanceÚdictÚ_declared_item_id)r+   Úitems   & r$   r-   r.   &   s*   é € ÐdÑ^cÐVZ´¸DÄ$×1GÒ1GÔ'¨Ô-ÈTÔQÓ^cùs   ‚02)
r2   Ústrr3   ÚlistÚtupleÚsetÚstripÚlowerÚaddÚappend)r   Ú
candidatesÚidsÚseenÚ	candidateÚmodel_ids   &     r$   Ú_declared_model_idsrC      s¹   € ä�%œ×ÒØ ˜'‰
Ü	�Eœ4×	 Ò	 át¡Ót‰
Ü	�EœD¤%˜=×	)Ò	)ÙdÑ^cÓd‰
àˆ	Ø€CÜ“U€DÛˆ	Ü˜)¤S×)Ò)ÙØ—?‘?Ó$ˆß‰8˜Ÿ™Ó(°Ö4Ø�H‰H�X—^‘^Ó%Ô&Ø�J‰J�xÖ ñ  ð €Jr&   c               ó    € V ^8„  d   QhRRRR/# )r   r5   r3   r    r   r"   )r#   s   "r$   r%   r%   5   s   € ÷ \ñ \˜Dð \ Sñ \r&   c                ó¢   € V P                  R4      p\        V\        4      '       d   VP                  4       '       d   V# V P                  R4      # )zQ``id`` of a ``[{"id": ...}]`` entry, falling back to ``name`` when blank/missing.ÚidÚname)Úgetr2   r6   r:   )r5   rB   s   & r$   r4   r4   5   s<   € à�x‰x˜‹~€HÜ! (¬C×0Ò0°X·^±^×5EÒ5Eˆ8Ð[È4Ï8É8ÐTZÓK[Ð[r&   c               ó    € V ^8„  d   QhRRRR/# )r   Úentryr   r    Úboolr"   )r#   s   "r$   r%   r%   ;   s   € ÷ 	Yñ 	Y Cð 	Y¨Dñ 	Yr&   c                óà   € \        V \        4      '       g   R# V P                  R4      pV P                  R4      RJ ;'       g,    \        V\        4      ;'       d    VP                  R4      RJ # )u  True when the entry's ``models`` mapping was auto-discovered by Hermes.

Current shape: entry-level ``models_discovered: true``. Older versions wrote an in-mapping
``__discovered_model_catalog__: true`` sentinel â€” accepted on read (the next save migrates it).FÚmodelsÚmodels_discoveredTr*   )r2   r3   rH   )rJ   rM   s   & r$   Ú_entry_models_discoveredrO   ;   sh   € ô
 �eœT×"Ò"ÙØ�Y‰Y�xÓ €FØ�9‰9Ð(Ó)¨TÐ1÷ Yð YÜ�6œ4Ó ×WÐW V§Z¡ZÐ0NÓ%OÐSWÐ%WðYr&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r   r   Ú
discoveredrK   r    r"   )r#   s   "r$   r%   r%   G   s!   € ÷ ñ  sð ¸ð Èñ r&   c                óØ   € V'       d   R# \        V \        4      '       d   \        V P                  4       4      # \        V \        \
        34      '       d   \        \        V 4      4      # R# )aï  True when ``models:`` is an intentional ID allowlist.

A mapping like ``{model_id: {context_length: N}}`` is per-model *metadata* written by
``_save_custom_provider`` / the wizard, not a catalog narrow (treating it as one made GUI
pickers show only the saved default for keyless Ollama while the CLI live-probed). List and
string shapes remain allowlists for no-key endpoints; pin a dict catalog with
``discover_models: false``. A catalog Hermes itself persisted (``discovered``) is never a pin.F)r2   r6   rK   r:   r7   r8   rC   )r   rQ   s   &&r$   Ú_models_config_is_allowlistrS   G   sM   € ÷ ÙÜ�%œ×ÒÜ�E—K‘K“MÓ"Ð"Ü�%œ$¤˜×'Ò'ÜÔ'¨Ó.Ó/Ð/Ùr&   c               ó    € V ^8„  d   QhRRRR/# )r   Úcurrent_base_urlr6   r    zOptional[ProviderDef]r"   )r#   s   "r$   r%   r%   X   s   € ÷ \ñ \°ð \Ð8Mñ \r&   c                óR   € \        V 4      pV'       g   R# \        RRRR	VRRRR7      # )
z=ProviderDef for a direct ``model.provider: custom`` endpoint.NÚcustomúCustom endpointÚopenai_chatFÚapi_keyzmodel-config)rF   rG   Ú	transportÚapi_key_env_varsÚbase_urlr   Ú	auth_typeÚsourcer"   )Ú_cleanr
   )rU   r]   s   & r$   Ú_bare_custom_provider_defra   X   s6   € äÐ&Ó'€HßÙÜØÐ+°}ÐWYØ¨¸)ÈNô\ð \r&   zöNous Research Hermes 3 & 4 models are NOT agentic and are not designed for use with Hermes Agent. They lack the tool-calling capabilities required for agent workflows. Consider using an agentic model instead (Claude, GPT, Gemini, DeepSeek, etc.).z&(?:^|[/:])hermes[-_ ]?[34](?:[-_.:]|$)ztuple[str, ...]Ú_OPAQUE_MODEL_PREFIXESc               ó    € V ^8„  d   QhRRRR/# ©r   Ú
model_namer6   r    r"   )r#   s   "r$   r%   r%   w   s   € ÷ ñ ¨ð °ñ r&   c                ó–   € \          F>  pV '       g   K  V P                  V4      '       g   K&  V \        V4      R ;'       g    T u # 	  V # )zZHuman-friendly form of *model_name* for CLI status output (display only, never wire-side).N)rb   Ú
startswithÚlen)re   Úprefixs   & r$   Úformat_model_for_displayrj   w   sB   € ç(ˆß‰:˜*×/Ñ/°×7Ô7Øœc &›k˜lÐ+×9Ð9¨zÒ9ñ )ð Ðr&   c               ó    € V ^8„  d   QhRRRR/# )r   re   r6   r    rK   r"   )r#   s   "r$   r%   r%      s   € ÷ Oñ O¨3ð O°4ñ Or&   c                óR   € \        T ;'       d    \        P                  V 4      4      # )z]True if *model_name* is a real Nous Hermes 3/4 chat model (single owner; cli.py uses it too).)rK   Ú_NOUS_HERMES_NON_AGENTIC_REÚsearch©re   s   &r$   Úis_nous_hermes_non_agenticrp      s!   € ä�
×MÐMÔ:×AÑAÀ*ÓMÓNÐNr&   c               ó    € V ^8„  d   QhRRRR/# rd   r"   )r#   s   "r$   r%   r%   „   s   € ÷ Sñ S¨Cð S°Cñ Sr&   c                ó4   € \        V 4      '       d   \        # R# )zHWarning string if *model_name* is a Nous Hermes 3/4 chat model, else "".Ú )rp   Ú_HERMES_MODEL_WARNINGro   s   &r$   Ú_check_hermes_model_warningru   „   s   € ä$>¸z×$JÒ$JÔ ÐRÐPRÐRr&   c                  ó0   € ] tR t^Œt$ RtR]R&   R]R&   RtR# )ÚModelIdentityz:Vendor slug and family prefix used for catalog resolution.r6   ÚvendorÚfamilyr"   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__Ú__static_attributes__r"   r&   r$   rw   rw   Œ   s   ‡ ÙDØƒKØ‡Kr&   rw   ÚsonnetÚ	anthropiczclaude-sonnetÚopuszclaude-opusÚhaikuzclaude-haikuÚclaudeÚgpt5Úopenaizgpt-5ÚgptÚcodexÚo3Úo4ÚgeminiÚgoogleÚdeepseekzdeepseek-chatÚgrokzx-aiÚllamaz
meta-llamaÚqwenÚminimaxÚnemotronÚnvidiaÚkimiÚ
moonshotaiÚglmzz-aiÚstepÚstepfunÚmimoÚxiaomiÚtrinityzarcee-aizdict[str, ModelIdentity]ÚMODEL_ALIASESc                  óV   € ] tR t^®t$ RtR]R&   R]R&   R]R&   RtR]R&   RtR]R&   R	tR
# )ÚDirectAliasa  Exact model mapping that bypasses catalog resolution.

``api_key`` / ``key_env`` carry the alias endpoint's OWN credential. Without them the switch
would keep the *default* provider's key, which 401s against the alias host and sends that
provider's secret to an unrelated third party. Both default so positional
``DirectAlias(model, provider, base_url)`` keeps working.

See #83612.
r6   ÚmodelÚproviderr]   rs   rZ   Úkey_envr"   N)	rz   r{   r|   r}   r~   r   rZ   r¢   r€   r"   r&   r$   rŸ   rŸ   ®   s,   ‡ ñð ƒJØƒMØƒMØ€GˆSÓØ€GˆS×r&   rŸ   údict[str, DirectAlias]Ú_BUILTIN_DIRECT_ALIASESc               ó    € V ^8„  d   QhRRRR/# ©r   r   r   r    r6   r"   )r#   s   "r$   r%   r%   Ã   s   € ÷ $ñ $�#ð $˜#ñ $r&   c                óH   € \        T ;'       g    R4      P                  4       # )uY   ``str(value or "").strip()`` â€” the config-field normaliser used throughout this module.rs   )r6   r:   )r   s   &r$   r`   r`   Ã   s   € äˆu�{ˆ{˜Ó×!Ñ!Ó#Ð#r&   ÚDIRECT_ALIASESc               ó    € V ^8„  d   QhRRRR/# )r   ÚcfgúOptional[dict]r    r£   r"   )r#   s   "r$   r%   r%   Ë   s   € ÷ 1ñ 1˜nð 1Ð8Nñ 1r&   c                ó€  € \        \        4      p V f   ^ RIHp V! 4       p V P	                  R4      p\        V\         4      '       dÜ   VP                  4        FÇ  w  rE\        V\         4      '       g   K  VP	                  RR4      '       g   K7  \        VP	                  RR4      VP	                  RR4      VP	                  RR4      \        VP	                  R	R4      4      \        VP	                  R
R4      4      R7      WP                  4       P                  4       &   KÉ  	  V P	                  R/ 4      p\        V\         4      '       d   VP	                  R4      MRp\        V\         4      '       Ed·   VP	                  RR4      pVP                  4        EF�  w  rIVP                  4       P                  4       p
V
'       d   W¡9   d   K4  \        V	\         4      '       d°   \        V	P	                  R4      4      pV'       dŒ   \        T\        V	P	                  R4      4      ;'       g    T;'       g    R\        V	P	                  RR4      4      \        V	P	                  R	R4      4      \        V	P	                  R
R4      4      R7      W&   K÷  Kù  \        V	\        4      '       g   EK  V	P                  4       '       g   EK+  V	P                  4       pRV9   d   VP                  R^4      MWŒ3w  rÛ\        VP                  4       VP                  4       ;'       g    TRR7      W&   EK’  	  V#   \         d     T# i ; i)u  Load direct aliases from config.yaml (or from the caller's *cfg* snapshot).

``model_aliases:`` entries are dicts (``model``, ``provider``, ``base_url``, optional
``api_key`` â€” literal or ``"${VAR}"`` â€” / ``key_env``); with neither credential field the key
is resolved from the alias HOST, never from the previously active provider. ``model.aliases``
never overrides ``model_aliases``; its string entries (``ds-flash: deepseek/deepseek-v4-flash``)
take the provider from the ``provider/`` prefix, else the current provider.

See #83612.
N©Úload_configÚmodel_aliasesr    rs   r¡   rW   r]   rZ   r¢   )r    r¡   r]   rZ   r¢   ÚaliasesÚ/©r    r¡   r]   )r3   r¤   Úhermes_cli.configr®   rH   r2   ÚitemsrŸ   r`   r:   r;   r6   ÚsplitÚ	Exception)rª   Úmergedr®   Úuser_aliasesrG   rJ   Úmodel_sectionÚsimple_aliasesÚcurrent_providerr   Úkeyr    Úvalr¡   s   &             r$   Ú_load_direct_aliasesr¾   Ë   sƒ  € ô Ô)Ó*€Fð$ØŠ;Ý5Ù“-ˆCà—w‘w˜Ó/ˆÜ�l¤D×)Ò)Ø+×1Ñ1Ö3‘�Ü˜e¤T×*Ô*¨u¯y©y¸À"×/EÔ/EÜ3>Ø#Ÿi™i¨°Ó4¸u¿y¹yÈÐU]Ó?^Ø!&§¡¨:°rÓ!:ÄFÈ5Ï9É9ÐU^Ð`bÓKcÓDdÜ & u§y¡y°¸BÓ'?Ó @ô4B�FŸ:™:›<×-Ñ-Ó/Ó0ñ  4ð Ÿ™ ¨Ó,ˆÜ9CÀMÔSW×9XÒ9X˜×*Ñ*¨9Ô5Ð^bˆÜ�n¤d×+Ó+Ø,×0Ñ0°¸RÓ@ÐØ-×3Ñ3×5‘�Ø—j‘j“l×(Ñ(Ó*�ß˜cœmÙÜ˜e¤T×*Ò*Ü" 5§9¡9¨WÓ#5Ó6�EßÜ&1Ø"'´&¸¿¹À:Ó9NÓ2O×2oÐ2oÐSc×2oÐ2oÐgoÜ%+¨E¯I©I°jÀ"Ó,EÓ%FÜ$*¨5¯9©9°YÀÓ+CÓ$DÜ$*¨5¯9©9°YÀÓ+CÓ$Dô	'F˜›ñ ô   ¤s×+Õ+°·±·µØŸ+™+›-�CØ;>À#¼: c§i¡i°°QÔ&7ÐL\ÐKb‘O�HÜ"-Ø#Ÿk™k›m°h·n±nÓ6F×6ZÐ6ZÐJZÐegô#i�F”Kñ  6ð& €Møô ô ØØ€Mðús?   ‘A L. Á6L. ÂFL. È+	L. È5A/L. Ê*L. ËAL. ÌL. Ì.L=Ì<L=úOptional[tuple]Ú_DIRECT_ALIAS_IDENTITYr«   Ú_DIRECT_ALIAS_LOADEDc               ó   € V ^8„  d   QhRR/# )r   r    r¿   r"   )r#   s   "r$   r%   r%   
  s   € ÷ -ñ - ñ -r&   c                 óæ   €  ^ RI Hp  V ! 4       p TP                  4       p\        T4      \        T4      3#   \         d     R# i ; i  \         d    \        T4      R3u # \         d     R# i ; i)zSIdentity of the active profile's alias source; None means "do not reuse the cache".)Úget_config_pathN)Úhermes_constantsrÄ   r¶   ÚstatÚOSErrorr6   r   )rÄ   ÚpathrÆ   s      r$   Ú_direct_alias_source_identityrÉ   
  sv   € ðÝ4ÙÓ ˆðØ�y‰y‹{ˆô �‹I”~ dÓ+Ð,Ð,øô ô Úðûô ô !ä�D“	˜4Ð Ò Üô Úðús,   ‚6 �A ¶AÁAÁA0Á"A0Á+A0Á/A0c               ó   € V ^8„  d   QhRR/# ©r   r    ÚNoner"   )r#   s   "r$   r%   r%     s   € ÷ (ñ ( ñ (r&   c                 óò   € \        4       p \        '       d!   \        \        8w  g   V e   V \        8X  d   R# \	        4       p\        P                  4        \        P                  V4       V s\        V4      sR# )zÁLoad direct aliases for the ACTIVE profile, caching per config identity.

Mutates DIRECT_ALIASES in place (never rebinds) so ``from ... import DIRECT_ALIASES``
references in callers stay valid.N)rÉ   r¨   rÁ   rÀ   r¾   ÚclearÚupdater3   )ÚidentityÚloadeds     r$   Ú_ensure_direct_aliasesrÒ     s]   € ô -Ó.€Hßƒ~äÔ.Ô.àÒ  XÔ1GÔ%GÙÜ!Ó#€FÜ×ÑÔÜ×Ñ˜&Ô!Ø%ÐÜ ›<Òr&   c               ó    € V ^8„  d   QhRRRR/# )r   ÚaliasrŸ   r    r6   r"   )r#   s   "r$   r%   r%   /  s   € ÷ :ñ : ð :°ñ :r&   c                óL  € V P                   ;'       g    RP                  4       pVP                  R4      '       d4   VP                  R4      '       d   \	        V^R P                  4       4      # V'       d   V# \	        V P
                  ;'       g    RP                  4       4      # )uS  Resolve a direct alias's own credential, or "" when it has none.

Precedence: ``api_key: "${VAR}"`` (env indirection) > literal ``api_key`` > ``key_env``.
Env reads go through the per-profile secret scope: a raw ``os.environ`` read hands this
profile whatever key the process env holds â€” another profile's, under the multiplexed gateway.rs   ú${Ú}éÿÿÿÿ)rZ   r:   rg   ÚendswithÚ_scoped_key_envr¢   )rÔ   Úraws   & r$   Údirect_alias_api_keyrÜ   /  s{   € ð �=‰=×Ð˜B×
%Ñ
%Ó
'€CØ
‡~�~�d×Ò §¡¨S× 1Ò 1Ü˜s 1 R˜yŸ™Ó0Ó1Ð1ß
Øˆ
Ü˜EŸM™M×/Ð/¨R×6Ñ6Ó8Ó9Ð9r&   c               ó    € V ^8„  d   QhRRRR/# )r   rÔ   rŸ   r    ztuple[str, Optional[str]]r"   )r#   s   "r$   r%   r%   =  s   € ÷ oñ o¨ð oÐ8Qñ or&   c                ó€   € V P                   '       d   RMV P                  ;'       g    R\        V 4      ;'       g    R3# )ue  ``(requested_provider, explicit_api_key)`` for resolving *alias*.

Single owner of the invariant that a URL-bearing direct alias resolves its credential for
the alias HOST, never for its provider label: a label like ``anthropic`` on an unrelated URL
would otherwise reach that provider's explicit-runtime branch and put the live vendor token
on the foreign wire. Bare ``custom`` is host-gated, so an authoritative URL still resolves
its vendor key and a foreign one resolves none. An alias with no base_url keeps its label â€”
there is no foreign host, and the label is the only routing information.

See #28660.
rW   N)r]   r¡   rÜ   )rÔ   s   &r$   Údirect_alias_runtime_requestrß   =  s5   € ð ŸŸ˜‰H¨U¯^©^×-GÐ-G¸xÔK_Ð`eÓKf×KnÐKnÐjnÐnÐnr&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úsession_base_urlr6   Úalias_base_urlr    rK   r"   )r#   s   "r$   r%   r%   P  s"   € ÷ <ñ <°Cð <Èð <ÐQUñ <r&   c                ó’   € \        V 4      p\        V4      pV^,          '       d   W#8w  d   R# Vw  rEpVR8H  ;'       g
    V\        9   # )aU  Whether the session's key may follow a switch to *alias_base_url*.

Same hostname is NOT sufficient: ``http://h`` and ``https://h:8443`` are different trust
boundaries, and an alias that drops the scheme would put a live bearer secret on the wire in
the clear. Require an identical (scheme, host, port) and refuse plaintext outside loopback.FÚhttps)r   Ú_LOOPBACK_HOSTS)rá   râ   ÚsessionrÔ   ÚschemeÚhostnameÚ_s   &&     r$   Ú_may_reuse_session_credentialrê   P  sL   € ô Ð.Ó/€GÜ˜NÓ+€EØ�1�:Œ:˜Ô)ÙØÑ€F�aØ�WÑ×;Ð; ¬OÑ ;Ð;r&   c                  óP   € ] tR tRt$ RtR]R&   RtR]R&   RtR]R&   RtR]R&   R	t	R
# )ÚStartupModelRoutei^  z<Model/provider pair resolved before an agent is constructed.r6   r    rs   r¡   r]   rZ   r"   N)
rz   r{   r|   r}   r~   r   r¡   r]   rZ   r€   r"   r&   r$   rì   rì   ^  s(   ‡ ÙFØƒJØ€HˆcÓØ€HˆcÓØ€GˆS×r&   rì   Úexplicit_providerrs   r»   Úuser_providersÚcustom_providersÚalias_configc               ó4   € V ^8„  d   QhRRRRRRRRRRR	RR
R/# )r   Ú	raw_modelr6   rí   r»   rî   r«   rï   úOptional[list]rð   r    zOptional[StartupModelRoute]r"   )r#   s   "r$   r%   r%   f  s_   € ÷ Scñ ScØðScØ*-ðScØFIðScà"ðScð %ðScð <JðScð VqñScr&   c               óN  a€ \        V 4      pV'       g   R# Vf   \        4        Vf   \        M
\        V4      pVP	                  VP                  4       4      pVec   V'       d"   \        VP                  WP                  R7      # \        V4      w  rš\        VP                  Y˜P                  T
;'       g    RR7      # V'       d   R# ^ RI
Hp ^ RIHo T;'       g    / P                  4        UUu0 uFQ  w  rÍ\        V\         4      '       g   K  S! \#        VP	                  R4      ;'       g    T4      \#        V4      4      kKS  	  pppTP%                  V3R lT;'       g    .  4       4       V! VRVR	7      w  ppV'       d   \        VVR
7      # RV9  d   R# R VP'                  R^4       4       w  ppV'       d	   V'       g   R# V'       d4    ^ RIHpHp V! V! V4      4      '       d   ^ RI
Hp V! V4      '       d   R# T;'       g    /  Uu0 uFK  p\#        V4      P1                  4       '       g   K$  \#        V4      P1                  4       P                  4       kKM  	  ppTP%                  R T;'       g    .  4       4        ^ RI
Hp V! V4      pVP                  4       V9   d   TpMVP                  4       V9   d   TpMR# \3        V4      '       d   R# \        VVR
7      # u uppi   \.         d     L÷i ; iu upi   \.         d    TP                  4       p L‹i ; i)uË  Resolve aliases, ``provider:model`` and configured ``provider/model`` input at startup.

``HermesCLI`` is constructed before the interactive ``/model`` pipeline runs; resolving here
keeps startup from attaching the configured default provider to an explicitly requested
model. ``provider/model`` strings are consumed only for providers present in user config. When
``current_provider`` is a routing aggregator and the raw string is an aggregator-native slug
(``anthropic/claude-opus-4.6`` on OpenRouter) the input stays on the aggregator â€” a
``providers:`` block for the same vendor must not steal the route. ``alias_config`` is a
caller's config snapshot to read aliases from instead of the process-global cache.Nr²   rs   )r    r¡   r]   rZ   )Úparse_model_input)Úcustom_provider_slugrG   c              3  óì   <"  € T Fi  p\        V\        4      '       g   K  \        VP                  R 4      4      '       g   K=  S! \	        VP                  R 4      ;'       g    R4      4      x € Kk  	  R# 5i©rG   rs   N)r2   r3   r`   rH   r6   )r+   rJ   rö   s   & €r$   r-   Ú.resolve_startup_model_route.<locals>.<genexpr>“  s`   øé € ð vÙ$:˜%¼zÈ%ÔQU×?Vô IÜ[aÐbg×bkÑbkÐlrÓbs×[tô IÑ*¬3¨u¯y©y¸Ó/@×/FÐ/FÀBÓ+G×HÐHÛ$:ùs   ƒA4 A4ÁA4Á!A4)Ú
custom_ids)r    r¡   r±   c              3  ó@   "  € T F  qP                  4       x € K  	  R # 5ir1   ©r:   ©r+   Úparts   & r$   r-   rù   š  s   é € Ð@Ñ.? d—Z‘Z—\�\Ó.?ùó   ‚)Úis_routing_aggregatorr   )Ú_find_openrouter_slugc              3  óø   "  € T Fp  p\        V\        4      '       g   K  \        VP                  R 4      4      '       g   K=  RVP                  R R4      P	                  4       P                  4        2x € Kr  	  R# 5i)rG   úcustom:rs   N)r2   r3   r`   rH   r:   r;   )r+   rJ   s   & r$   r-   rù   ©  s_   é € ð Bá,ˆEÜ�eœT×"ô 	:ä'-¨e¯i©i¸Ó.?×'@ô 	:ˆ'�%—)‘)˜F BÓ'×-Ñ-Ó/×5Ñ5Ó7Ð8Õ9Û,ùs   ‚A:ŸA:Á9A:)r   )r`   rÒ   r¨   r¾   rH   r;   rì   r    r]   rß   Úhermes_cli.modelsrõ   Úhermes_cli.providersrö   r´   r2   r3   r6   rÏ   rµ   r   r   r  r¶   r:   r   )rò   rí   r»   rî   rï   rð   rÛ   r°   ÚdirectÚalias_providerÚ	alias_keyrõ   r¼   rJ   rú   Úqualified_providerÚqualified_modelri   r    r   Ú
_norm_provr  rG   Ú
configuredr   Ú	canonicalr¡   rö   s   &$$$$$                     @r$   Úresolve_startup_model_router  f  sÌ  ø€ ô �Ó
€CßÙàÒÜÔ Ø ,Ò 4�nÔ:NÈ|Ó:\€GØ�[‰[˜Ÿ™›Ó%€FØÒßô %¨6¯<©<ÐBS×^mÑ^mÔnÐnô %AÀÓ$HÑ!ˆÜ Ø—,‘,¨Ç/Á/Ð[d×[jÐ[jÐhjôlð 	l÷ Ùõ
 4Ý9à%3×%9Ð%9°r×$@Ñ$@Ô$Bô_Ù$B‘j�cÄjÐQVÔX\×F]ô PÑ&¤s¨5¯9©9°VÓ+<×+CÐ+CÀÓ'DÄcÈ#ÃhÖOÙ$Bð ñ _à×Ñô vØ$4×$:Ð$:¸Ð$:óvô vá*;¸CÀÐPZÔ*[Ñ'Ð˜ßÜ  ÐASÔTÐTØ
�#„~ÙÙ@¨c¯i©i¸¸QÔ.?Ó@�M€FˆEßŸÙçð	ßdÙ$¡ZÐ0@Ó%A×BÒBÝCÙ(¨×-Ò-Ùð :H×9MÐ9MÈ2Ð9MÓdÑ9M°ÔRUÐVZÓR[×RaÑRa×RcÔ+”#�d“)—/‘/Ó#×)Ñ)Ö+Ñ9M€JÐdØ×Ññ Bà&×,Ð,¨"Ð,óBô Bð#Ý8Ù& vÓ.ˆ	ð ‡|�|ƒ~˜Ô#Ø‰Ø	�‰Ó	˜jÔ	(Ø‰áÜ  ×+Ò+ˆ4ÐbÔ1BÈÐYaÔ1bÐbùóQ_øô( ô 	Ùð	üò eøô ô #Ø—L‘L“NŠ	ð#úsH   Ã2K*ÄK*Ä0K*ÇK0 Ç0K0 È!LÈ:+LÊ
L Ë0K>Ë=K>ÌL$Ì#L$c                  ó  € ] tR tRt$ RtR]R&   RtR]R&   RtR]R&   R	tR]R
&   Rt	R]R&   Rt
R]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   RtR]R&   R	tR]R&   R	tR]R&   RtR# )ÚModelSwitchResulti¾  z!Result of a model switch attempt.rK   Úsuccessrs   r6   Ú	new_modelÚtarget_providerFÚprovider_changedrZ   r]   Úapi_modeNr«   Úrequest_overridesÚerror_messageÚwarning_messageÚusage_noticeÚprovider_labelÚresolved_via_aliaszOptional[ModelCapabilities]ÚcapabilitieszOptional[dict[str, bool]]Úruntime_capabilitiesúOptional[ModelInfo]Ú
model_infoÚ	is_globalÚalias_endpoint_appliedr"   )rz   r{   r|   r}   r~   r   r  r  r  rZ   r]   r  r  r  r  r  r  r  r  r  r  r   r!  r€   r"   r&   r$   r  r  ¾  sÀ   ‡ á+ØƒMØ€IˆsÓØ€O�SÓØ"Ð�dÓ"Ø€GˆSÓØ€HˆcÓØ€HˆcÓØ(,Ð�~Ó,Ø€M�3ÓØ€O�SÓð €L�#ÓØ€N�CÓØ Ð˜Ó Ø04€LÐ-Ó4Ø6:ÐÐ3Ó:Ø&*€JÐ#Ó*Ø€IˆtÓð $)Ð˜D×(r&   r  T)Úfrozenc                  óz   € ] tR tRt$ RtR]R&   RtR]R&   RtR]R&   RtR	]R
&   Rt	R	]R&   Rt
R	]R&   RtR	]R&   RtR# )ÚModelFlagParseResultiÚ  z"Parsed flags for a /model command.r6   Úmodel_inputrs   rí   Úreasoning_effortFrK   r   Úforce_refreshÚ
is_sessionÚis_oncer"   N)rz   r{   r|   r}   r~   r   rí   r&  r   r'  r(  r)  r€   r"   r&   r$   r$  r$  Ú  sI   ‡ á,ØÓØÐ�sÓØÐ�cÓØ€IˆtÓØ€M�4ÓØ€J�ÓØ€GˆT×r&   r$  z--globalr   z	--sessionr(  z	--refreshr'  z--oncer)  z
--providerz--reasoningr&  c               ó    € V ^8„  d   QhRRRR/# )r   Úraw_argsr6   r    r$  r"   )r#   s   "r$   r%   r%   ì  s   € ÷ [ñ [¨ð [Ð1Eñ [r&   c                ó&  € \         P                  ! RRV 4      p \        P                  \        P                  4       R4      p\        P                  \        P                  4       R4      p. p\        V P                  4       4      pV F]  pV\        9   d   RV\        V,          &   K   V\        9   d"   \        VR4      ;pe   Wb\        V,          &   KL  VP                  V4       K_  	  \        R	RRP                  V4      P                  4       /VBVB # )
a-  Parse /model flags: ``--provider X``, ``--reasoning <level>``, ``--global``, ``--session``,
``--refresh``, ``--once``.

``--once`` is parsed here but interpreted by each caller (each frontend has its own
live-session restore hook). ``is_global`` / ``is_session`` are raw flag presences; the
effective persistence decision belongs to :func:`resolve_persist_behavior`. ``reasoning_effort``
is the raw level word (validated by :func:`hermes_constants.parse_reasoning_effort` at apply
time) so a model pick and its effort travel as ONE request on every surface.zJ[\u2012\u2013\u2014\u2015](provider|reasoning|global|session|refresh|once)z--\1Frs   TNr%  Ú r"   )ÚreÚsubr3   ÚfromkeysÚ_BOOL_FLAGSÚvaluesÚ_VALUE_FLAGSÚiterrµ   Únextr=   r$  Újoinr:   )r+  Úflagsr2  ÚfilteredÚtokensÚtokr   s   &      r$   Úparse_model_flags_detailedr;  ì  sã   € ô �vŠvÐcÐelÐnvÓw€Hô "Ÿ]™]¬;×+=Ñ+=Ó+?ÀÓG€EÜ!Ÿ]™]¬<×+>Ñ+>Ó+@À"ÓE€FØ€HÜ�(—.‘.Ó"Ó#€FÛˆØ”+ÔØ&*ˆE”+˜cÕ"Ó#Ø”LÔ ¬t°F¸DÓ/AÐ&A eÒ%NØ(-”< Õ$Ó%à�O‰O˜CÖ ñ ô  ÑZ¨C¯H©H°XÓ,>×,DÑ,DÓ,FÐZÈ&ÐZÐTYÑZÐZr&   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )r   r   rK   r(  r)  rí   r6   r    r"   )r#   s   "r$   r%   r%   	  s4   € ÷ !ñ !Øð!Ø!%ð!Ø04ð!ØQTð!Ø^bñ!r&   c                ó�  € V'       g	   V'       d   R# V '       d   R#  ^ RI Hp V! 4       P                  R4      p\	        T\
        4      '       d`   TP                  R4      '       g   TP                  R4      '       g   R# \        TP                  RR4      4      '       d   R# T'       d   R# R# T'       * #   \         d     R# i ; i)uæ  Decide whether a ``/model`` switch should persist to ``config.yaml``.

Order: ``--once`` / ``--session`` -> False; ``--global`` -> True; no default configured yet
(neither ``model.default`` nor ``model.provider`` â€” a fresh install's first pick) -> True, so
the pick does not evaporate into whatever ``*_API_KEY`` is lying around on the next launch;
``model.persist_switch_by_default`` -> True (the user's explicit opt-in to persistence);
``--provider`` without a persist flag -> False (exploratory). A flat-string ``model`` IS a configured
default; an unreadable config -> False.

1. ``--once`` explicitly opts out â†’ ``False`` (next turn only). 2. ``--session`` explicitly opts out â†’
``False`` (this session only). 3. 4. Applies to every surface (CLI, gateway, Desktop picker) so no
client has to hardcode ``--global``. 5. ``model.persist_switch_by_default: true`` also covers provider picks (a pick between two providers sharing one ``base_url`` is tenant selection on the same backend, not exploration;
session-scoping it silently serves the next chat with the other twin's key). 6. Without that opt-in, provider switches stay exploratory â€” the user is trying a different backend for this conversation, not reconfiguring the default. The key defaults to ``False`` (a plain ``/model <name>`` affects only the current session); users who want the old persist-by-default behavior can set it to ``true``; a one-off ``--global`` always persists, and ``--session`` / ``--once`` always opt out. See #86414.
FTr­   r    Údefaultr¡   Úpersist_switch_by_default)r³   r®   rH   r¶   r2   r3   rK   )r   r(  r)  rí   r®   Ú	model_cfgs   &&&&  r$   Úresolve_persist_behaviorrA  	  sš   € ÷  —*ÙßÙðÝ1Ù“M×%Ñ% gÓ.ˆ	ô �)œT×"Ò"Ø—‘˜i×(Ò(¨I¯M©M¸*×,EÒ,EÙÜ�	—‘Ð9¸5ÓA×BÒBÙßÙÙØŒ=Ðøô ô Úðús   žB6 Â6CÃCÚonce_with_globalÚonce_requires_targetÚbad_reasoningz./model --once cannot be combined with --globalz+/model --once requires a model or provider.zO/model --reasoning takes none, minimal, low, medium, high, xhigh, max or ultra.c                  óÂ   € ] tR tRt$ RtR]R&   R]R&   RtR]R&   RtR]R&   R	tR
]R&   R	t	R
]R&   R	t
R
]R&   R	tR
]R&   RtR]R&   RtR]R&   ]R R l4       tR R ltRtR# )ÚModelSwitchRequesti>  aŸ  A fully parsed /model command request.

``scope`` is the *requested* persistence scope from the flags alone: ``"once"`` |
``"session"`` | ``"global"`` | ``"default"`` (the effective decision then belongs to
:func:`resolve_persist_behavior`). ``errors`` carries ``MODEL_SWITCH_ERR_*`` codes rendered
via :data:`MODEL_SWITCH_ERROR_TEXT`. ``model_input`` keeps it a drop-in for
:class:`ModelFlagParseResult` consumers.r6   rÛ   Útargetrs   rí   r&  FrK   r   r(  r)  r'  r>  Úscoper8   Úerrorsc               ó   € V ^8„  d   QhRR/# ©r   r    r6   r"   )r#   s   "r$   r%   ÚModelSwitchRequest.__annotate__S  s   € ÷ ñ ˜Sñ r&   c                	ó   € V P                   # r1   )rG  ©Úselfs   &r$   r%  ÚModelSwitchRequest.model_inputR  s   € à�{‰{Ðr&   c               ó   € V ^8„  d   QhRR/# )r   r    r7   r"   )r#   s   "r$   r%   rL  V  s   € ÷ Gñ G ñ Gr&   c                óZ   € V P                    Uu. uF  p\        V,          NK  	  up# u upi )z8Canonical (undercorated) error strings for this request.)rI  ÚMODEL_SWITCH_ERROR_TEXT)rO  Úcodes   & r$   Úerror_messagesÚ!ModelSwitchRequest.error_messagesV  s'   € à:>¿+º+ÓF¹+°$Ô'¨×-Ð-¹+ÑFÐFùÒFs   �(r"   N)rz   r{   r|   r}   r~   r   rí   r&  r   r(  r)  r'  rH  rI  Úpropertyr%  rU  r€   r"   r&   r$   rF  rF  >  sƒ   ‡ ñ0ð 
ƒHØƒKØÐ�sÓØÐ�cÓØ€IˆtÓØ€J�ÓØ€GˆTÓØ€M�4ÓØ€Eˆ3ÓØ€FˆEÓàôó ð÷Gñ Gr&   rF  c               ó    € V ^8„  d   QhRRRR/# )r   rÛ   r6   r    rF  r"   )r#   s   "r$   r%   r%   [  s   € ÷ wñ w ð wÐ);ñ wr&   c                óÎ  € \        T ;'       g    R4      p \        V 4      p. pVP                  '       d(   VP                  '       d   VP	                  \
        4       VP                  '       d:   VP                  '       g(   VP                  '       g   VP	                  \        4       VP                  '       d0   ^ RI
Hp V! VP                  4      f   VP	                  \        4       \        R RVP                  3RVP                  3RVP                  33 4       R4      p\        RRV R	VP                  R
VR\!        V4      /R Uu/ uF  pV\#        W4      bK  	  upB # u upi )a¬  The ONE parser for every /model surface: tokenization plus flag-conflict validation.

``--once`` + ``--global`` -> ``MODEL_SWITCH_ERR_ONCE_WITH_GLOBAL``; ``--once`` with neither
a model nor ``--provider`` -> ``MODEL_SWITCH_ERR_ONCE_REQUIRES_TARGET``; an unknown
``--reasoning`` level -> ``MODEL_SWITCH_ERR_BAD_REASONING``. Targets pass through
untouched (bare names, ``vendor/model``, ``vendor:model``) for :func:`switch_model`.rs   )Úparse_reasoning_effortc              3  ó>   "  € T F  w  rV'       g   K  Vx € K  	  R # 5ir1   r"   )r+   rG   Úons   &  r$   r-   Ú*parse_model_switch_args.<locals>.<genexpr>o  s%   é € ð Mñ (F™8˜4ÜIK÷ ’$ó (Fùs   ‚“
Úonceræ   Úglobalr>  rÛ   rG  rH  rI  r"   )rí   r&  r   r(  r)  r'  )r6   r;  r)  r   r=   Ú!MODEL_SWITCH_ERR_ONCE_WITH_GLOBALr%  rí   Ú%MODEL_SWITCH_ERR_ONCE_REQUIRES_TARGETr&  rÅ   rZ  ÚMODEL_SWITCH_ERR_BAD_REASONINGr5  r(  rF  r8   Úgetattr)rÛ   ÚparsedrI  rZ  rH  Úfs   &     r$   Úparse_model_switch_argsrf  [  sU  € ô ˆc�iˆi�R‹.€CÜ'¨Ó,€Fà€FØ‡~‡~€~˜&×*×*Ð*Ø�‰Ô7Ô8Ø‡~‡~€~˜f×0×0Ð0¸×9Q×9QÐ9QØ�‰Ô;Ô<Ø××ÐÝ;Ù! &×"9Ñ"9Ó:ÒBØ�M‰MÔ8Ô9äñ M¨°·±Ð(@À9Èf×N_ÑN_ÐB`Ø)1°6×3CÑ3CÐ(Dñ(Fó MØNWóY€Eäñ wØðwØ×*Ñ*ðwØ27ðwÜ@EÀfÃðwñ uóvÙtˆqð Œg�fÓ Ò Ùtñvñwð wùòvs   ÅE"c               ó    € V ^8„  d   QhRRRR/# r¦   r"   )r#   s   "r$   r%   r%   w  s   € ÷ @ñ @ cð @¨cñ @r&   c                óê   € \        V \        4      '       d   V P                  4       # \        V \        4      '       d   \	        V P                  R4      4      # \        V RR4      pVe   \	        V4      # R# )z?Extract a model-name candidate from a str / dict / attr-object.r    Nrs   )r2   r6   r:   r3   r`   rH   rc  )r   Ú
model_attrs   & r$   Ú_effective_model_candidaterj  w  s_   € ä�%œ×ÒØ�{‰{‹}ÐÜ�%œ×ÒÜ�e—i‘i Ó(Ó)Ð)Ü˜ ¨Ó.€JØ!+Ò!7Œ6�*ÓÐ?¸RÐ?r&   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   Úsession_overridesr   Úchannel_configÚglobal_configr    r6   r"   )r#   s   "r$   r%   r%   �  s,   € ÷ ñ ØðØ36ðØNQðØ[^ñr&   c                óJ   € WV3 F  p\        V4      pV'       g   K  Vu # 	  R# )a7  Resolve the effective model: session override > channel > global.

Single owner of the precedence rule gateway/run.py and api_server.py each used to encode.
Each argument may be a model string, a dict with a ``"model"`` key, or an object with a
``.model`` attribute; empty entries fall through to the next tier.rs   )rj  )rl  rm  rn  ÚtierrA   s   &&&  r$   Úresolve_effective_modelrq  �  s.   € ð #°MÓBˆÜ.¨tÓ4ˆ	ß‰9ØÒñ Cñ r&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rB   r6   ri   r    r8   r"   )r#   s   "r$   r%   r%   ‘  s!   € ÷ :ñ :˜cð :¨3ð :°5ñ :r&   c                ó¾  € V \        V4      R P                  R4      P                  R4      P                  4       p\	        V4      w  r4VP                  4       P                  R4      P                  4       p\        ;QJ d    . R V 4       F  NK  	  5M! R V 4       4      p\        R V 4       RR7      pVR8X  d   R
MR	V) 3pVR9   d   ^ M^p	WiV3,           V,           # )zÞSort key preferring higher versions after the family prefix, then ranked suffix tokens.

With prefix ``"mimo"``: ``mimo-v2.5-pro`` -> (-2.5, 0, 'pro'), ``mimo-v2.5`` -> (-2.5, 1, ''),
``mimo-v2-omni`` -> (-2.0, 1, 'omni').Nr±   Ú-ú-_.c              3  ó8   "  € T F  qR 8  g   K  V) x € K  	  R# 5i©i%ë!Nr"   ©r+   Úns   & r$   r-   Ú"_model_sort_key.<locals>.<genexpr>Ÿ  s   é € Ð;¡D˜q°
©Nœ˜�£Dùs   ‚�c              3  ó6   "  € T F  qR 8¼  g   K  Vx € K  	  R# 5irw  r"   rx  s   & r$   r-   rz     s   é € Ð9¡˜A¨j©—a’a£ùr/   ç        )r>  g      ð?)r|  r|  )ÚproÚmaxÚplusÚturboÚsolÚastra)rh   ÚremoveprefixÚlstripr:   Ú_split_version_suffixr;   r8   r~  )
rB   ri   ÚrestÚnumsÚ
suffix_bufÚsuffixÚversion_keyÚ
date_stampÚdate_keyÚsuffix_ranks
   &&        r$   Ú_model_sort_keyrŽ  ‘  sÎ   € ð ”C˜“K�LÐ!×.Ñ.¨sÓ3×:Ñ:¸3Ó?×EÑEÓG€DÜ,¨TÓ2Ñ€DØ×ÑÓ×%Ñ% eÓ,×2Ñ2Ó4€F÷ ”%Ñ;¡DÓ;—%‘%Ñ;¡DÓ;Ó;€KÜÑ9¡Ó9À3ÔG€JØ'¨3Ô.‰z°S¸:¸+Ð4F€Hð Ð!PÔP‘!ÐVW€KØ vÐ.Õ.°Õ9Ð9r&   c               ó    € V ^8„  d   QhRRRR/# )r   r†  r6   r    ztuple[list[float], str]r"   )r#   s   "r$   r%   r%   «  s   € ÷ "ñ " ð "Ð(?ñ "r&   c                ó  aa€ . oR^ uopR VV3R llpV\        V 4      8  dá   W,          pVR9   d   V^,          pK*  VR9   g   VP                  4       '       g   M¨VR9   d
   V^,          pV\        V 4      8  d`   W,          P                  4       '       g   W,          R8X  d7   W,          R8X  d   RS9   d	   V! 4        MSW,          ,          oV^,          pKo  V! 4        V\        V 4      8  g   Kà  W,          R9  g   Kï   SWR 3# )	zû``"v2.5-pro"`` -> ``([2.5], "pro")``; ``"-omni"`` -> ``([], "omni")``.

Version tokens are ``v``-optional digit/dot runs separated by ``-``/``_``; a second dot inside
a run starts a new component; the first character that is neither starts the suffix.rs   c               ó   € V ^8„  d   QhRR/# rË   r"   )r#   s   "r$   r%   Ú+_split_version_suffix.<locals>.__annotate__³  s   € ÷ ñ �Dñ r&   c                 óˆ   <€  S P                  \        SP                  R 4      4      4       RoR#   \         d     RoR# i ; i)Ú.rs   N)r=   ÚfloatÚrstripÚ
ValueError)r‡  Úruns   €€r$   Ú_flushÚ%_split_version_suffix.<locals>._flush³  sA   ø€ ð	Ø�K‰Kœ˜cŸj™j¨›oÓ.Ô/ð Šøô ô 	ØØŠð	ús   ƒ)0 °AÁ Aru  ÚvVr”  z-_N)rh   Úisdigit)r†  Úposr™  Úchr‡  r˜  s   &   @@r$   r…  r…  «  sã   ù€ ð
 €DØ�1€H€Cˆ÷ñ ð ”�D“	Œ/Ø�YˆØ�Œ;Ø�1�HˆCÙØ�d”
˜bŸj™jŸlšlØØ�Œ:Ø�1�HˆCØ”C˜“IŒo 4¥9×#4Ñ#4×#6Ò#6¸$½)ÀsÔ:JØ�y˜CÔ C¨3¤JÙ•à�t•yÕ �Ø�1�HŠCÙŒØ”�T“Ž?˜t�y°Ö4ØØ��d�ÐÐr&   c                  ó2   a € ] tR tRtRtR V 3R lltRtV ;t# )ÚAmbiguousAliasErroriÐ  zÿAlias family-matches multiple catalog models; caller must disambiguate.

Raised by :func:`resolve_alias` instead of silently picking one via version-sort heuristics.
``candidates`` is sorted best-guess-first (see :func:`_model_sort_key`) for display only.c               ó$   € V ^8„  d   QhRRRRRR/# )r   rÔ   r6   r¡   r>   r!   r"   )r#   s   "r$   r%   Ú AmbiguousAliasError.__annotate__Õ  s&   € ÷ \ñ \˜cð \¨Sð \¸iñ \r&   c                	óp   <€ Wn         W n        W0n        \        SV `  R V: R\        V4       RV 24       R# )zalias z	 matches ú models on N)rÔ   r¡   r>   ÚsuperÚ__init__rh   )rO  rÔ   r¡   r>   Ú	__class__s   &&&&€r$   r¦  ÚAmbiguousAliasError.__init__Õ  s8   ø€ ØŒ
Ø ŒØ$ŒÜ‰Ñ˜6 %¡¨)´C¸
³OÐ3DÀKÐPXÈzÐZÖ[r&   )rÔ   r>   r¡   )rz   r{   r|   r}   r~   r¦  r€   Ú__classcell__)r§  s   @r$   r   r   Ð  s   ø† ña÷\ö \r&   r   c               ó    € V ^8„  d   QhRRRR/# )r   Úerrr   r    r6   r"   )r#   s   "r$   r%   r%   Ü  s   € ÷ 	5ñ 	5Ð"5ð 	5¸#ñ 	5r&   c           
     óD  € V P                   R,          pRP                  R \        V^4       4       4      p\        V P                   4      \        V4      ,
          pV^ 8”  d   RV R2MRpRV P                   R\        V P                   4       R	V P
                   R
V V R2
# )z7User-facing disambiguation list for an ambiguous alias.:Né
   NÚ
c              3  ó6   "  € T F  w  rR V RV 2x € K  	  R# 5i)z  z. Nr"   )r+   ÚiÚms   &  r$   r-   Ú+_ambiguous_alias_message.<locals>.<genexpr>ß  s    é € ÐDÑ0C©¨˜˜1˜#˜R ˜s•mÓ0Cùs   ‚u   
  â€¦ and z morers   Ú'z
' matches r¤  u"    â€” not switching automatically:
z)
Pick one with /model <exact-model-name>.)r>   r6  Ú	enumeraterh   rÔ   r¡   )r«  ÚshownÚlinesÚhiddenÚmores   &    r$   Ú_ambiguous_alias_messager¹  Ü  s™   € à�N‰N˜3Õ€EØ�I‰IÑD´	¸%ÀÔ0CÓDÓD€EÜ�—‘Ó ¤3 u£:Õ-€FØ+1°A¬:ˆ\˜&˜ Ñ'¸2€Dà
ˆC�I‰Iˆ;�j¤ S§^¡^Ó!4Ð 5°[Ø�<‰<ˆ.Ð;¸E¸7À4À&ð I3ð	4ð5r&   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rG   r6   rî   r«   rï   ró   r    r"   )r#   s   "r$   r%   r%   è  s0   € ÷ Kñ K˜Sð K°.ð KØ)7ðKØCFñKr&   c                óx   € V '       d   \        WV4      MRpVe   VP                  # \        T ;'       g    R4      # )z­Id a provider name routes to, e.g. ``custom:<name>`` for a legacy ``custom_providers``
entry, so an alias naming it by its bare name compares equal to the resolved provider.Nrs   )r   rF   r   )rG   rî   rï   Úpdefs   &&& r$   Ú_provider_identityr½  è  s9   € ÷ MQÔ  Ð7GÔHÐVZ€DØÒ&ˆ4�7‰7ÐJÔ,>¸t¿z¸zÀrÓ,JÐJr&   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   Ú	raw_inputr6   r»   rî   r«   rï   ró   r    úOptional[tuple[str, str, str]]r"   )r#   s   "r$   r%   r%   ð  s8   € ÷ E/ñ E/˜Sð E/°Cð E/Èð E/Ø$2ðE/Ø>\ñE/r&   c                ó   aa€ V P                  4       P                  4       p\        4        \        P	                  V4      pVe   VP
                  VP                  V3# Rp\        WV4      p\        P                  4        F{  w  r‰V	P                  P                  4       V8w  d   K&  \        V	P
                  W#4      V8X  d   V	P
                  V	P                  V3u # Ve   Kb  V	P
                  V	P                  V3pK}  	  Ve   V# \        V4      w  r«V
'       d   \        W«WAR7      pVe   WV3# \        P	                  V4      pVf   R# Vw  rïV
'       d   \        W«WñR7      pV'       d   WV3# R# \        V4      p ^ RIHp V Uu0 uF  pVP                  4       kK  	  upoVP                  V3R lVP	                  V. 4       4       4       \#        V4      '       d   V RV 2MToV Uu. uF:  pVP                  4       P%                  SP                  4       4      '       g   K8  VNK<  	  ppV'       g   R# VP'                  V3R lR7       \)        V4      ^8”  d   \+        WAV4      hVV^ ,          V3# u upi   \          d     Lºi ; iu upi )a�  Resolve a short alias against the current provider's catalog.

Direct aliases (and reverse lookup by exact model id) win; then :data:`MODEL_ALIASES` is
matched against the provider's models.dev catalog by ``vendor/family`` prefix (``family``
for non-aggregators). Returns ``(provider, resolved_model_id, alias_name)`` or None; raises
:class:`AmbiguousAliasError` when several catalog models match.N)r¡   )Ú_PROVIDER_MODELSc              3  óT   <"  € T F  qP                  4       S9  g   K  Vx € K  	  R # 5ir1   ©r;   )r+   r±  r@   s   & €r$   r-   Ú resolve_alias.<locals>.<genexpr>&  s$   øé € ÐfÑ"L˜Q×PWÑPWÓPYÐaeÑPe—q’qÓ"Lùó   ƒ(ž
(r±   c                ó   <€ \        V S4      # r1   )rŽ  )r±  ri   s   &€r$   Ú<lambda>Úresolve_alias.<locals>.<lambda>2  s   ø€ œ¨q°&Ô9r&   )r¼   )r:   r;   rÒ   r¨   rH   r¡   r    r½  r´   Ú_external_process_catalogÚ_external_process_matchr�   r   r  rÂ  Úextendr¶   r   rg   Úsortrh   r   )r¿  r»   rî   rï   r¼   r  Úreverse_fallbackÚ
current_idÚ
alias_nameÚdaÚprocess_catalogÚprocess_aliasesÚdeclaredrÐ   rx   ry   ÚcatalogrÂ  r±  ÚmidÚmatchesri   r@   s   &&&&                 @@r$   Úresolve_aliasrØ  ð  sK  ù€ ð �/‰/Ó
×
!Ñ
!Ó
#€CäÔÜ×Ñ Ó$€FØÒØ—‘ §¡¨sÐ3Ð3ð 8<ÐÜ#Ð$4ÐFVÓW€JÜ(×.Ñ.Ö0‰ˆ
Ø�8‰8�>‰>Ó˜sÔ"ÙÜ˜bŸk™k¨>ÓLÐPZÔZØ—K‘K §¡¨:Ð6Ò6ØÔ#Ø "§¡¨R¯X©X°zÐBÒñ 1ð Ò#ØÐä'@ÐAQÓ'RÑ$€Oßô +¨?ÈSÔlˆØÒØ$°Ð4Ð4ä× Ñ  Ó%€HØÒÙà�N€FçÜ*¨?ÈVÔoˆß4<Ð ¨CÐ0ÐFÀ$ÐFô #Ð#3Ó4€GðÝ6Ù#*Ó+¡7˜a�—‘–	¡7Ñ+ˆØ�‰ÔfÐ"2×"6Ñ"6Ð7GÈÔ"LÓfÔfô &3Ð3C×%DÒ%D�ˆx�q˜˜Ñ!È&€FÙ%ÓP™g�s¨¯©«×)?Ñ)?ÀÇÁÃ×)O�sˆs™g€GÐPßÙð
 ‡L�LÔ9€LÔ:Ü
ˆ7ƒ|�aÔÜ! #¸ÓAÐAØ˜g a�j¨#Ð.Ð.ùò! ,øäô Ùðüò Qs0   Å<
I: ÆI5Æ.I: Ç+5JÈ%JÉ5I: É:JÊJc               ó    € V ^8„  d   QhRRRR/# )r   r¡   r6   r    z tuple[list[str], dict[str, str]]r"   )r#   s   "r$   r%   r%   8  s   € ÷ cñ c¨ð cÐ0Pñ cr&   c                ó   € ^ RI Hp V! V 4      pVe   VP                  R8w  d   . / 3# \        VP                  4      VP
                  P                  4        UUu/ uF  w  r4VP                  4       VbK  	  upp3# u uppi )zU``(declared model ids, own aliases)`` of an ``external_process`` profile, else empty.)Úget_provider_profileÚexternal_process)Ú	providersrÛ  r^   r7   Úfallback_modelsr¯   r´   r;   )r¡   rÛ  Úprofiler,   Úvs   &    r$   rÊ  rÊ  8  sp   € å.Ù" 8Ó,€GØ‚˜'×+Ñ+Ð/AÔAØ�2ˆvˆÜ�×'Ñ'Ó(ÀG×DYÑDY×D_ÑD_ÔDaÔ*bÑDa¹D¸A¨1¯7©7«9°aª<ÑDaÒ*bÐbÐbùÓ*bs   ÁA:c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r   rÕ  r!   r°   údict[str, str]Útypedr6   r¡   r    ú
str | Noner"   )r#   s   "r$   r%   r%   A  s2   € ÷ +ñ + Yð +¸ð +ÐPSð +Ðbeð +Ðjtñ +r&   c               ón  a€ VP                  4       P                  4       oSV9   d
   VS,          # \        V3R lV  4       R4      pVe   V# V  Uu. uF+  qUP                  4       P                  S4      '       g   K)  VNK-  	  pp\	        V4      ^8”  d   \        SW64      hV'       d
   V^ ,          # R# u upi )z«Provider alias, exact id, else the single declared id that extends it (``claude-opus-5``
-> ``claude-opus-5[1m]``); several candidates raise so nothing is picked silently.c              3  óT   <"  € T F  qP                  4       S8X  g   K  Vx € K  	  R # 5ir1   rÄ  )r+   r±  Úwanteds   & €r$   r-   Ú*_external_process_match.<locals>.<genexpr>G  s   øé € Ð<™W˜¯©«	°VÑ(;—!’!›WùrÆ  N)r:   r;   r5  rg   rh   r   )rÕ  r°   rã  r¡   Úexactr±  r×  rç  s   &&&$   @r$   rË  rË  A  sŸ   ø€ ð �[‰[‹]× Ñ Ó"€FØ�ÔØ�v�ÐÜÔ<™WÓ<¸dÓC€EØÒØˆÙ!ÓB™'�Q§W¡W£Y×%9Ñ%9¸&×%A�qˆq™'€GÐBÜ
ˆ7ƒ|�aÔÜ! &¨(Ó<Ð<ß ˆ7�1�:Ð* dÐ*ùò Cs   Á&B2Á;B2c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r»   r6   rî   údict | Nonerï   úlist | Noner    r!   r"   )r#   s   "r$   r%   r%   P  s,   € ÷ 
ñ 
Øð
Ø0;ð
ØVað
àñ
r&   c                ó~   €  \        WV^ RR7       Uu. uF  q3R,          NK  	  up# u upi   \         d    . u # i ; i)z–Slugs of providers that have credentials (models.dev in-memory cache + disk catalog cache;
stale catalogs warm in the background, never in this call).T)r»   rî   rï   Ú
max_modelsÚnon_blocking_catalogsÚslug)r   r¶   )r»   rî   rï   Úps   &&& r$   Ú get_authenticated_provider_slugsrò  P  s^   € ð
Ü#?Ø-Ø-¸!ÐSWõ$Yó Zñ $Y˜a�&—	�	ñ $Yñ Zð 	Zùò Zøô ô ØŠ	ðús   ‚, “'¤, §, ¬<»<c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# )r   r¿  r6   Úauthenticated_providersr!   rî   r«   rï   ró   r    rÀ  r"   )r#   s   "r$   r%   r%   ]  s4   € ÷ 	=ñ 	=Øð	=Ø-6ð	=ØM[ð	=à$ð	=à0Nñ	=r&   c                ó^   a aa€ VV V3R lT;'       g    R 4       p\        R V 4       R4      # )u  Resolve an alias on the user's authenticated providers (``("openrouter", "nous")`` when none given).

AmbiguousAliasError propagates: the alias exists on this provider, the user just has to
choose â€” trying the next provider would silently switch them somewhere they didn't ask for.c              3  ó@   <"  € T F  p\        SVSS4      x € K  	  R # 5ir1   )rØ  )r+   rñ  rï   r¿  rî   s   & €€€r$   r-   Ú*_resolve_alias_fallback.<locals>.<genexpr>d  s(   øé € ð KÙI�1ô ˜Y¨¨>Ð;K×LÐLÛIùs   ƒc              3  ó0   "  € T F  qf   K  Vx € K  	  R # 5ir1   r"   )r+   Úrs   & r$   r-   r÷  f  s   é € Ð5™G�q—’›Gùs   ‚Œ
N)Ú
openrouterÚnous)r5  )r¿  rô  rî   rï   Úresultss   f&ff r$   Ú_resolve_alias_fallbackrý  ]  s3   ú€ öKØ/×IÐIÐ3IÐIóK€GäÑ5™GÓ5°tÓ<Ð<r&   c               óD   € V ^8„  d   QhRRRRRRRRRRRR	R
RRRRRRRRR/# )r   r    r6   r¡   r]   rZ   r  r  rï   rì  Úconfig_context_lengthz
int | NoneÚconfigured_modelrä  Úconfigured_providerÚconfigured_base_urlr    úOptional[int]r"   )r#   s   "r$   r%   r%   i  sp   € ÷ %ñ %Øð%Øð%Ø),ð%Ø<?ð%à#ð%à>Ið%ð &ð%ð AKð%ð $ð	%ð
 $ð%ð
 0=ñ%r&   c
           	     ó˜  € Ve2   V'       g   V'       g	   V	'       d    ^ RI Hp
 V
! WpW’W�4      '       d   Rp ^ RIHp T! Y;'       g    RT;'       g    RT;'       g    RWVR7      pV'       d   \        V4      #  Ve(   VP                  '       d   \        VP                  4      # R#   \         d    Rp L�i ; i  \         d     LMi ; i)uw  Context length to show in /model output.

models.dev reports per-vendor context but provider-enforced limits can be lower (Codex OAuth
caps gpt-5.5 at 272k), so ``agent.model_metadata.get_model_context_length`` is authoritative
(it also honors ``custom_providers[].models.<id>.context_length``); ``model_info.context_window``
is the fallback. A ``config_context_length`` pin is dropped when the route changed.

When ``custom_providers`` is provided, per-model ``context_length`` overrides from
``custom_providers[].models.<id>.context_length`` are honored â€” this closes #15779 where ``/model``
switch ignored user-set overrides.
N©Úshould_clear_context_pin)Úget_model_context_lengthrs   )r]   rZ   r¡   rï   rÿ  )Úhermes_cli.route_identityr  r¶   Úagent.model_metadatar  ÚintÚcontext_window)r    r¡   r]   rZ   r  rï   rÿ  r   r  r  r  r  Úctxs   &&&&&&&&&&   r$   Úresolve_display_context_lengthr  i  sÏ   € ð" Ò(×.>×BU×Ylð	)ÝJÙ'Ø$Ð-@ÐL_÷kò kà(,Ð%ðÝAÙ&ØŸN˜N¨°G·M°M¸rÈH×L\ÐL\ÐX\Ø-ô\ˆ÷ Ü�s“8ˆOð ð Ò *×";×";Ð";Ü�:×,Ñ,Ó-Ð-Ùøô ô 	)Ø$(Ò!ð	)ûô ô Ùðús4   žB( ·B; Á
B; Á
B; ÁB; Â(B8Â7B8Â;C	ÃC	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r    r6   r¡   r    r  r"   )r#   s   "r$   r%   r%   ‘  s'   € ÷ ^ñ ^°cð ^ÀSð ^ÐWdñ ^r&   c              ‹  óV   "  € ^ RI pVP                  ! \        W3/ VB G Rj  x€L
 #  L5i)u¹   Thread-offloaded :func:`resolve_display_context_length` (same keyword arguments) â€” the sync
version runs blocking provider probes that async gateway handlers must not run on the loop.N)ÚasyncioÚ	to_threadr  )r    r¡   Úkwargsr  s   &&, r$   Ú$resolve_display_context_length_asyncr  ‘  s*   é € ó Ø×"Ò"Ô#AÀ5Ñ]ÐV\Ñ]×]Ð]Ñ]ùs   ‚ )¢'£)c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   re   r6   rî   r«   rï   ró   r    râ  r"   )r#   s   "r$   r%   r%   š  s,   € ÷ $ñ $Øð$Ø%3ð$ØGUð$àñ$r&   c           	     óp  aa€ V '       d   V P                  4       '       g   / # V P                  4       P                  4       o. p\        V\        4      '       d\   Y1P	                  4        UUu. uF8  w  rE\        V\
        4      '       g   K  \        V\        4      '       g   K5  WE3NK:  	  upp,          pV UUu/ uF  w  rEV\        WE4      bK  	  ppp\        V4       Uu. uFW  p\        VP                  R4      \
        4      '       g   K*  VR,          P                  4       '       g   KI  RVR,           2V3NKY  	  pp/ p	W8,            FX  w  po\        VV3R lR 4       R4      p
V
'       g   K'  WF9  d   \        VSV4      MRpT	P                  T;'       g    TV
4       KZ  	  V	# u uppi u uppi u upi )u#  ``{provider_slug: canonical_model_id}`` for every configured provider whose declared models
(``models``, ``model``, ``default_model`` â€” exact, case-insensitive, never fuzzy) contain
``model_name``, so a typed name routes to the provider that declares it instead of being
soft-accepted by the current provider (openai-codex) as an unknown hidden model.

Used by :func:`switch_model` to route a *typed* model name to the provider that actually declares it in
user/custom provider config, instead of leaving it on the current provider. See #45006.
rG   r  c              3  ó–   <"  € T F>  p\        SP                  V4      4       F  q"P                  4       S8X  g   K  Vx € K  	  K@  	  R # 5ir1   )rC   rH   r;   )r+   r¼   rÖ  rª   rG  s   &  €€r$   r-   Ú/_configured_provider_matches.<locals>.<genexpr>¹  sA   øé € ð [Ñ#G˜CÜ2°3·7±7¸3³<Ö@˜ÇIÁIÃKÐSYÑDY÷ ’CÙ@ñ Ó#Gùs
   ƒ3A	»A	N)rM   r    Údefault_model)r:   r;   r2   r3   r´   r6   Ú_configured_provider_identityÚ_custom_entriesrH   r5  Ú_duplicates_configured_rowÚ
setdefault)re   rî   rï   r>   rð  rª   ÚrowsÚeÚentriesr×  ÚhitÚownerrG  s   &&&  `      @r$   Ú_configured_provider_matchesr"  š  s•  ù€ ÷ ˜Z×-Ñ-×/Ò/Øˆ	Ø×ÑÓ×%Ñ%Ó'€Fà)+€JÜ�.¤$×'Ò'Ø×4HÑ4HÔ4Jô KÑ4J¡y tÜ$ T¬3×/ô #Ü4>¸sÄD×4Iô #˜“{Ñ4Jò Kõ 	Kˆ
ñ MWÔWÉJ¹y¸tˆDÔ/°Ó:Ò:ÉJ€DÑWÜ3BÐCSÔ3Tó HÑ3T¨aÜ˜QŸU™U 6›]¬C×0ô *Ø56°vµY·_±_×5Fô *�'˜!˜F�)˜Ð% qÓ)Ñ3T€Gð Hð !€GØ×)Ð)‰	ˆˆcÜõ [Ñ#Gó [Ø\`óbˆç‰3ØCGÔCSÔ.¨t°S¸$Ô?ÐY]ˆEØ×Ñ˜uŸ}˜}¨¨cÖ2ñ *ð €Nùó'Kùó XùòHs*   Á,F'ÂF'Â#F'Â9F-Ã 'F3ÄF3Ä+F3c               ó$   € V ^8„  d   QhRRRRRR/# )r   rð  r6   rª   r3   r    ztuple[str, str, str, str]r"   )r#   s   "r$   r%   r%   Á  s'   € ÷ añ a¨ð a°$ð aÐ;Tñ ar&   c                óØ  € ^ RI HpHp T! VP                  4        UUu/ uF  w  rEVR8w  g   K  WEbK  	  uppV P	                  R4      '       d   RMT R7      ;'       g    Tp\        VP                  R4      4      P                  4       ;'       g     V P                  R4      P                  4       P                  RR4      p\        VP                  R	4      ;'       g+    VP                  R
4      ;'       g    VP                  R4      4      P                  R4      P                  4       p\        VP                  R4      4      \        VP                  R4      ;'       g    VP                  R4      4      r©V	P	                  R4      '       d,   V	P                  R4      '       d   RV	^R P                  4       r©V	'       d   RV	 2MKV
'       d   RV
 2M>\        VP                  R4      4      '       d   R\        VP                  R4      4       2MRp\        VP                  R4      ;'       g    VP                  R4      4      pYxY¼'       d   V! V4      P                  4       3# R3# u uppi )a_  ``(name, endpoint, credential, api_mode)`` of one configured provider, read through the same
normalizer that builds the compat view, so a ``providers.<slug>`` row, its ``custom:<name>``
projection and a legacy duplicate of the same endpoint reduce to one tuple. Any difference in
endpoint, credential identity or wire protocol keeps two rows distinct.)Ú_canonical_api_modeÚ _normalize_custom_provider_entryÚprovider_keyr  rs   )r'  rG   r-  rt  r]   ÚurlÚapir±   rZ   r¢   Úapi_key_envrÖ   r×   zkey:zenv:Úkey_cmdzcmd:r  r[   rØ   )Úhermes_cli.config_providersr%  r&  r´   rg   r`   rH   r;   rƒ  Úreplacer–  rÙ   r:   )rð  rª   r%  r&  r,   rà  rJ   rG   r]   rZ   r¢   Ú
credentialr  s   &&           r$   r  r  Á  sÿ  € ÷
 bñ -¸s¿y¹y¼{Ô-b¹{±t°qÈaÐSaÑNa¬d¨aªd¹{Ò-bØ@DÇÁÐPY×@ZÒ@Z¹"Ð`dôf÷ mð mØilð 
ä�5—9‘9˜VÓ$Ó%×+Ñ+Ó-×UÐU°×1BÑ1BÀ9Ó1M×1SÑ1SÓ1U×^Ñ^Ð_bÐdgÓh€DÜ�e—i‘i 
Ó+×SÐS¨u¯y©y¸Ó/?×SÐSÀ5Ç9Á9ÈUÓCSÓT×[Ñ[Ð\_Ó`×fÑfÓh€HÜ˜eŸi™i¨	Ó2Ó3´V¸E¿I¹IÀiÓ<P×<lÐ<lÐTY×T]ÑT]Ð^kÓTlÓ5mˆWØ×Ñ˜$×Ò G×$4Ñ$4°S×$9Ò$9Ø˜w q¨˜}×2Ñ2Ó4�ß&-�D˜˜	Ñ"Çw°T¸'¸Ñ3CÜ@FÀuÇyÁyÐQZÓG[×@\Ò@\˜œf U§Y¡Y¨yÓ%9Ó:Ð;Ñ<Ðbdð ä�e—i‘i 
Ó+×EÐE¨u¯y©y¸Ó/EÓF€HØ˜:ÖPXÑ':¸8Ó'D×'JÑ'JÓ'LÐ`Ð`Ð^`Ð`Ð`ùó .cs
   žI&
®I&
c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   rð  r6   rJ   r3   r  z$dict[str, tuple[str, str, str, str]]r    úOptional[str]r"   )r#   s   "r$   r%   r%   Ö  s2   € ÷ 
pñ 
pØð
pØð
pØ&Jð
pØO\ñ
pr&   c                ó¶   aa€ \        W4      o\        VP                  R4      4      P                  4       o\	        VV3R lVP                  4        4       R4      # )u†  Slug of the ``providers.<slug>`` row a ``custom_providers`` entry is a second view of, else
None: the row's compat projection (``provider_key`` names the slug AND it points at the same
endpoint with the same credential â€” on the raw-list fallback a hand-written provider_key aimed
at another endpoint or another key stays a candidate) or a legacy duplicate with the same
provider identity.r'  c              3  ó–   <"  € T F>  w  rSV8X  g/   SVP                  4       8X  g   K#  SR ,          VR ,          8X  g   K:  Vx € K@  	  R# 5i):é   é   NNrÄ  )r+   Úrow_slugÚrowrÐ   r'  s   &  €€r$   r-   Ú-_duplicates_configured_row.<locals>.<genexpr>ß  sI   øé € ð i©|™m˜hØ ”O¨¸¿¹Ó8HÑ(Hô ØMUÐVYÍ]Ð^aÐbeÕ^fÑMf÷ ’«|ùs   ƒ A	¨A	¿
A	N)r  r`   rH   r;   r5  r´   )rð  rJ   r  rÐ   r'  s   &&&@@r$   r  r  Ö  sQ   ù€ ô -¨TÓ9€HÜ˜%Ÿ)™) NÓ3Ó4×:Ñ:Ó<€LÜõ i¨t¯z©z¬|ó iØjnópð pr&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   ÚstÚ_SwitchÚcfg_matchesrâ  r    r0  r"   )r#   s   "r$   r%   r%   ã  s&   € ÷ 	nñ 	n ð 	n°nð 	nÈñ 	nr&   c                ó  aa€ V P                   V9   d   V P                   # \        V P                   4      P                  4       o\        V P                  \
        4      '       d   V P                  M/ o\        VV3R lV 4       R4      # )u
  The slug in *cfg_matches* the session already runs on: an exact hit, or â€” for a session on
the compat projection slug (``custom:relay``) of ``providers.relay`` â€” that row's slug, so a
same-provider switch keeps the caller's slug instead of flipping it (#112788).c           	   3  óî   <"  € T Fj  p\        SP                  V4      \        4      '       g   K*  S\        \	        SV,          P                  R 4      ;'       g    R4      V4      9   g   Kf  Vx € Kl  	  R# 5irø   )r2   rH   r3   r   r6   )r+   rð  ÚcurrentrÝ  s   & €€r$   r-   Ú*_current_provider_match.<locals>.<genexpr>ë  s]   øé € ð g¡+˜$´¸I¿M¹MÈ$Ó<OÔQU×1V”ØÔ 7¼¸IÀd½O×<OÑ<OÐPVÓ<W×<]Ð<]Ð[]Ó8^Ð`dÓ eÑe÷ ’£+ùs   ƒ'A5¯)A5ÁA5Á+
A5N)r»   r`   r;   r2   rî   r3   r5  )r9  r;  r>  rÝ  s   &&@@r$   Ú_current_provider_matchr@  ã  sw   ù€ ð 
×Ñ˜kÔ)Ø×"Ñ"Ð"Ü�R×(Ñ(Ó)×/Ñ/Ó1€GÜ%/°×0AÑ0AÄ4×%HÒ%H�×!Ò!Èb€IÜõ g¡+ó gØhlónð nr&   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   re   r6   r  rï   ró   r    r"   )r#   s   "r$   r%   r%   ï  s*   € ÷ ñ ¨sð ÀSð Ð\jð Ðorñ r&   c                óä  € \        V4      P                  4       pVP                  R4      '       d   RV 9  d   V # R V P                  R^4       4       w  rEV'       d	   V'       g   V # \	        V4       Fz  p\        V4      pW79   g   K  RVP                  4        2V9   g   K0  \        VP                  R4      4       F,  pVP                  4       VP                  4       8X  g   K(  Vu u # 	  K|  	  V # )zUMap a picker-prefixed custom model selection (``prefix/model``) to its configured ID.r  r±   c              3  ó@   "  € T F  qP                  4       x € K  	  R # 5ir1   rü   rý   s   & r$   r-   Ú1_resolve_named_custom_model_id.<locals>.<genexpr>õ  s   é € ÐKÑ2J¨$Ÿ™Ÿ˜Ó2Jùrÿ   rM   )r`   r;   rg   rµ   r  Ú_entry_aliasesrC   rH   )	re   r  rï   r¡   ri   rA   rJ   Úentry_slugsrB   s	   &&&      r$   Ú_resolve_named_custom_model_idrG  ï  sÉ   € ä�oÓ&×,Ñ,Ó.€HØ×Ñ˜y×)Ò)¨S¸
Ô-BØÐáK°*×2BÑ2BÀ3ÈÔ2JÓKÑ€FßŸØÐÜ Ð!1Ö2ˆÜ$ UÓ+ˆØÖ"¨°·±³Ð0@Ð'AÀ[Ö'PÜ/°·	±	¸(Ó0CÖD�Ø—>‘>Ó# y§¡Ó'8Ö8Ø#”Oó Eñ 3ð Ðr&   c               ó    € V ^8„  d   QhRRRR/# )r   rï   r   r    z
list[dict]r"   )r#   s   "r$   r%   r%     s   € ÷ nñ n cð n¨jñ nr&   c                ó�   € \        V \        4      '       d+   V  Uu. uF  p\        V\        4      '       g   K  VNK  	  up# . # u upi )zSThe dict-shaped entries of a ``custom_providers:`` list (anything else is ignored).)r2   r7   r3   )rï   r  s   & r$   r  r    s<   € äCMÐN^Ô`d×CeÒCeÑ'Ó?Ñ'�!¬:°a¼×+>�AˆAÑ'Ñ?ÐmÐkmÐmùÒ?s
   ›A¸Ac               ó    € V ^8„  d   QhRRRR/# )r   rJ   r3   r    zfrozenset[str]r"   )r#   s   "r$   r%   r%     s   € ÷ gñ g˜$ð g >ñ gr&   c                ó¢   € \        \        V P                  R 4      ;'       g    R4      \        V P                  R4      ;'       g    R4      4      # )rG   rs   r'  )r   r6   rH   )rJ   s   &r$   rE  rE    s<   € Ü"¤3 u§y¡y°Ó'8×'>Ð'>¸BÓ#?ÄÀUÇYÁYÈ~ÓE^×EdÐEdÐbdÓAeÓfÐfr&   c               ó    € V ^8„  d   QhRRRR/# )r   rª   r3   r    r6   r"   )r#   s   "r$   r%   r%     s   € ÷ 	ñ 	˜tð 	°#ñ 	r&   c                óH  € \        V P                  RR4      4      pVP                  R4      '       d#   VP                  R4      '       d   V! V^R 4      pV'       gF   \        V P                  R4      ;'       g    V P                  R4      4      pV'       d	   V! V4      MRpV# )ztInline ``api_key`` (a ``${VAR}`` template resolves via *read_env*), else
``key_env``/``api_key_env`` via *read_env*.rZ   rs   rÖ   r×   r¢   r*  rØ   )r`   rH   rg   rÙ   )rª   Úread_envr¼   r¢   s   &&  r$   Ú_entry_configured_keyrO    s€   € ô �—‘˜ BÓ'Ó
(€CØ
‡~�~�d×Ò §¡¨S× 1Ò 1Ù�s˜1˜R�yÓ!ˆßÜ˜Ÿ™ Ó+×EÐE¨s¯w©w°}Ó/EÓFˆß#*‰h�wÔ°ˆØ€Jr&   c               ó   € V ^8„  d   QhRR/# )r   r    ztuple[dict, str]r"   )r#   s   "r$   r%   r%     s   € ÷ Pñ PÐ!1ñ Pr&   c                 óº   € ^ RI Hp  V ! R4      pT\        VP                  R4      ;'       g+    VP                  R4      ;'       g    VP                  R4      4      3# )é    )Ú_get_provider_config_dictÚollamar]   r)  r(  )r  rS  r`   rH   )rS  rª   s     r$   Ú_ollama_configured_baserU    sH   € Ý;Ù
# HÓ
-€CØ”�s—w‘w˜zÓ*×NÐN¨c¯g©g°e«n×NÐNÀÇÁÈÃÓOÐOÐOr&   c               ó    € V ^8„  d   QhRRRR/# )r   rí   r6   r    r"   )r#   s   "r$   r%   r%     s   € ÷ ñ °ð ¸ñ r&   c                ó¼   € R V  R2p ^ RI Hp V! 4       pV'       d.   VRRP                  R VR,           4       4      ,           ,          pV#   \         d     T# i ; i)zUnknown provider 'z`'. Check 'hermes model' for available providers, or define it in config.yaml under 'providers:'.)Úvalidate_config_structureu1   

Run 'hermes doctor' â€” config issues detected:rs   c              3  ó@   "  € T F  pR VP                    2x € K  	  R# 5i)u   
  â€¢ N)Úmessage)r+   Úcis   & r$   r-   Ú,_unknown_provider_message.<locals>.<genexpr>&  s'   é € ð  SAÑuÐoqÐU]Ð^`×^hÑ^hÐ]iÕSjÓuùrÿ   :Nr4  N)r³   rX  r6  r¶   )rí   ÚmsgrX  Úissuess   &   r$   Ú_unknown_provider_messager_    s‡   € à
Ð.Ð/ð 0Eð 	Fð ðÝ?Ù*Ó,ˆßØÐHÈ2Ï7É7ñ  SAÐu{Ð|~Öuó  SAó  LAõ  Aõ  AˆCð €Jøô ô ØØ€Jðús   ˆA �-A ÁAÁAc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   rí   r6   r  r»   r    r"   )r#   s   "r$   r%   r%   ,  s,   € ÷ 1ñ 1Øð1Ø-0ð1ØDGð1àñ1r&   c                ó¬  € ^ RI Hp ^ RIHp V P	                  4       P                  4       pVP                  V4      pV'       d   W�8X  d   W8w  d   W9   g   R# \        W#VR7      p	W9   d   R# V	 U
u. uF%  qªP                  V4      '       g   K  W§8w  g   K#  V
NK'  	  pp
V'       d   RRP                  V4       R2MRpRV R	\        V4       R
V 2# u up
i )a	  Guard against silent aggregator hops: a vendor alias like bare "openai" resolves to an
aggregator ("openrouter"); if that aggregator has no credentials, refuse instead of switching
the user onto an unauthed endpoint (HTTP 401) and point at the real direct provider.)Ú_AGGREGATOR_PROVIDERS)ÚALIASESrs   ©r»   rî   rï   z Did you mean: ú, Ú?ú
Provider 'z"' is an alias that routes through z&, which has no credentials configured.)r  rb  r  rc  r:   r;   rH   rò  rg   r6  r   )rí   r  r»   rî   rï   rb  rc  Úexplicit_normÚalias_targetÚauthedÚsÚsuggestionsÚhints   &&&&&        r$   Ú_aggregator_alias_errorrn  ,  sÒ   € õ 8Ý,Ø%×+Ñ+Ó-×3Ñ3Ó5€MØ—;‘;˜}Ó-€Lç˜Ô8¸_Ô=]ØÔ4ÙÜ-Ø)Ð[kôm€FàÔ ÙÙ$Ó[™f˜¯©°]×(C”1ÈÑHZ—1�1™f€KÐ[ß:Eˆ_˜TŸY™Y {Ó3Ð4°AÑ6È2€Dà
�]�Oð $Ü˜_Ó-Ð.ð /)Ø)-¨ð	0ð1ùò \s   Á1CÂCÂCc               ó$   € V ^8„  d   QhRRRRRR/# )r   r  r6   rÕ  r7   r    rä  r"   )r#   s   "r$   r%   r%   F  s&   € ÷ añ a¨ð a°tð aÀ
ñ ar&   c                óŒ   a€ V P                  4       o\        V3R lV 4       R4      ;'       g    \        V3R lV 4       R4      # )zSExact (case-insensitive) match on full id, then on the bare part after ``vendor/``.c              3  óT   <"  € T F  qP                  4       S8X  g   K  Vx € K  	  R # 5ir1   rÄ  ©r+   rÖ  rç  s   & €r$   r-   Ú,_aggregator_catalog_match.<locals>.<genexpr>I  s   øé € ÐA¡˜¯9©9«;¸&Ñ+@—’£ùrÆ  Nc              3  ó–   <"  € T F>  pR V9   g   K  VP                  R ^4      ^,          P                  4       S8X  g   K:  Vx € K@  	  R# 5i)r±   N)rµ   r;   rr  s   & €r$   r-   rs  J  s<   øé € ÐY™� 3¨#¡:Œ°#·)±)¸CÀÓ2CÀAÕ2F×2LÑ2LÓ2NÐRXÑ2X�Š›ùs   ƒ	A	‘)A	¿
A	)r;   r5  )r  rÕ  rç  s   &&@r$   Ú_aggregator_catalog_matchru  F  sE   ø€ à�_‰_Ó€FÜÔA¡ÓAÀ4ÓH÷ að aÌDÜY™ÓYÐ[_óMað ar&   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r  r6   r  r]   r    rK   r"   )r#   s   "r$   r%   r%   M  s,   € ÷ ñ ØðØ%(ðØ47ðØ^bñr&   c                ó°  € V'       dL   ^ RI Hp VP                  V4      pVe1   V! V4      '       d#   V \        VP                  R/ 4      4      9   d   R# \	        V4       Fs  pVP                  4       \        V4      9   g   VP                  RR4      V8X  g   K:  WP                  RR4      8X  g#   V \        VP                  R/ 4      4      9   g   Kr   R# 	  R# )zÒA model declared in the user's ``providers:``/``custom_providers:`` config is accepted even
when the remote /v1/models does not list it (cloud/aliased models). Custom entries match by
slug alias or by base_url.)Úis_provider_enabledrM   Tr]   rs   r    F)r³   rx  rH   rC   r  r;   rE  )r  r  r]   rî   rï   rx  rª   rJ   s   &&&&&   r$   Ú_config_declares_modelry  M  sº   € ÷
 Ý9Ø× Ñ  Ó1ˆØŠ?Ñ2°3×7Ò7¸IÔI\Ð]`×]dÑ]dÐemÐoqÓ]rÓIsÔ<sÙÜ Ð!1Ö2ˆØ×!Ñ!Ó#¤~°eÓ'<Ô<ÀÇ	Á	È*ÐVXÓ@YÐ]eÖ@eØŸ™ 7¨BÓ/Ô/°9Ô@SÐTY×T]ÑT]Ð^fÐhjÓTkÓ@lÖ3lâñ	 3ñ
 r&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r9  r:  rÑ  rŸ   r    rÌ   r"   )r#   s   "r$   r%   r%   _  s!   € ÷ -ñ - Wð -°+ð -À$ñ -r&   c                ó
  € ^ RI Hp ^ RIHp \	        V4      p\        V P                  VP                  4      pV'       d   VP                  VuV n        V n        MßV P                  '       d,   V P                  R8w  d   V'       d   VP                  V n        M¢ \        V4      w  rgV! WgVP                  V P                  R7      pVP                  RR4      ;'       g    VP                  V n        VP                  RR4      p	V	R8X  d   Rp	T	;'       g!    V'       d   V P                  MR;'       g    RV n        V'       g�   V P                  P                  4       P                  4       R8X  d`   \        4       w  r«V'       d6   V! V P                  V4      '       d   \!        V
R	 4      pV'       d   WÀn        M/ R
RuV n        V n        V n        V P                  ;'       g    RV n        RV n        R#   \         d    / p EL=i ; i)a  Route a direct alias to its own base_url and decide its credential (mutates ``st``).

Credentials were resolved against the DEFAULT provider; carrying that key onto the alias
endpoint both 401s and ships the default provider's secret to an unrelated host. The alias's
own endpoint decides: its declared key; else the session key only for the SAME ORIGIN; else a
fresh resolution against the alias base_url (env-key fallbacks are host-gated: OLLAMA_API_KEY
resolves for ollama.com, OPENROUTER_API_KEY never reaches an unrelated host).)Ú_same_ollama_native_root©Úresolve_runtime_providerúno-key-required)Ú	requestedÚexplicit_api_keyÚexplicit_base_urlÚtarget_modelr]   rs   rZ   rT  c                ó^   € \         P                  P                  V R 4      P                  4       # ©rs   )ÚosÚenvironrH   r:   )ry  s   &r$   rÈ  Ú._apply_direct_alias_endpoint.<locals>.<lambda>…  s   € ÌÏÉÏÉÐXYÐ[]ÓI^×IdÑIdÔIfr&   TN)Úhermes_cli.models_localr|  Úhermes_cli.runtime_providerr~  rÜ   rê   r]   rZ   rß   r  r¶   rH   r  r:   r;   rU  rO  Úvalidation_headersÚsuppress_ollama_headersr  )r9  rÑ  r|  r~  r  Ú	same_hostÚreqÚexplicitÚalias_runtimeÚresolved_keyÚ
ollama_cfgÚollama_cfg_baseÚconfigured_keys   &&           r$   Ú_apply_direct_alias_endpointr•  _  sœ  € õ AÝDÜ$ RÓ(€IÜ-¨b¯k©k¸2¿;¹;ÓG€IßØ"$§+¡+¨yÐˆŒ�R•ZØ	��ˆ˜Ÿ
™
Ð&7Ô7¿Ià—k‘kˆ�ð	Ü8¸Ó<‰MˆCÙ4ØÈBÏKÉKÐfh×frÑfrôtˆMð $×'Ñ'¨
°BÓ7×FÐF¸2¿;¹;ˆŒð %×(Ñ(¨°BÓ7ˆØÐ,Ô,ØˆLØ!×[Ð[·I b§j¢jÀ2×[Ð[ÐJ[ˆŒ
÷
 ˜×+Ñ+×1Ñ1Ó3×9Ñ9Ó;¸xÔGÜ&=Ó&?Ñ#ˆ
ßÑ7¸¿¹À_×UÒUÜ2°:Ñ?fÓgˆNßØ+”
øð MOÐPTÐVgÐIˆBÔ! 2Ô#=¸r¼zØ—‘×0Ð0Ð0€B„JØ€B†Køô/ ô 	Ø‹Mð	ús   Â,G1 Ç1HÈHc               ó   € V ^8„  d   QhRR/# rK  r"   )r#   s   "r$   r%   r%   �  s   € ÷ ñ ˜Sñ r&   c                 óš   €  ^ RI Hp  ^ RIHp T! V ! 4       P	                  R4      ;'       g    / 4      R,          #   \
         d     R# i ; i)rR  r­   )Únormalize_moa_configÚmoaÚdefault_presetr>  )r³   r®   Úhermes_cli.moa_configr˜  rH   r¶   )r®   r˜  s     r$   Ú_moa_default_presetrœ  �  sE   € ðÝ1Ý>Ù#¡K£M×$5Ñ$5°eÓ$<×$BÐ$BÀÓCÐDTÕUÐUøÜô Úðús   ‚*; ­; »A
Á	A
c                  óf  € ] tR tRt$ RtR]R&   R]R&   R]R&   R]R&   R]R&   R	]R
&   R]R&   R]R&   R]R&   RtR]R&   RtR]R&   RtR]R&   Rt	R	]R&   Rt
R]R&   RtR]R&   RtR]R&   RtR]R&   ]! ]R7      tR]R&   RtR	]R&   ]! ]R7      tR]R&   R R  ltR! R" lt]R# R$ l4       tR% R& ltR'tR(# ))r:  i˜  af  Mutable state threaded through the ``switch_model`` steps.

The routing steps settle ``target_provider`` / ``new_model`` / ``resolved_alias`` (and may
promote a config-routed ``providers.<slug>`` to ``explicit_provider`` so the credential step
resolves its block); the credential step fills ``api_key`` / ``base_url`` / ``api_mode`` /
``validation_headers``.r6   r¿  r»   Úcurrent_modelrU   Úcurrent_api_keyrK   r   rí   r«   rî   ró   rï   rs   r  r  Úresolved_aliasFr!  r  rZ   r]   r  )Údefault_factoryr3   r‹  rŒ  Ú
validationc               ó    € V ^8„  d   QhRRRR/# ©r   rZ  r6   r    r  r"   )r#   s   "r$   r%   Ú_Switch.__annotate__µ  s   € ÷ kñ k˜Cð kÐ.?ñ kr&   c           	     	ó8   € \        RR RRV P                  RV/VB # )r  Fr   r  r"   )r  r   )rO  rZ  Úfieldss   &&,r$   ÚfailÚ_Switch.failµ  s%   € Ü Ñj¨Ðj¸$¿.¹.ÐjÐX_ÐjÐciÑjÐjr&   c               ó    € V ^8„  d   QhRRRR/# r¤  r"   )r#   s   "r$   r%   r¥  ¸  s   € ÷ lñ l cð lÐ.?ñ lr&   c                óP   € V P                  WP                  V P                  R7      # )zNFailure carrying the already-settled ``target_provider`` / ``provider_label``.)r  r  )r¨  r  r  )rO  rZ  s   &&r$   Úfail_on_targetÚ_Switch.fail_on_target¸  s"   € à�y‰y˜×2FÑ2FÐW[×WjÑWjˆyÓkÐkr&   c               ó   € V ^8„  d   QhRR/# )r   r    rK   r"   )r#   s   "r$   r%   r¥  ½  s   € ÷ =ñ = $ñ =r&   c                	ó4   € V P                   V P                  8g  # r1   )r  r»   rN  s   &r$   r  Ú_Switch.provider_changed¼  s   € à×#Ñ# t×'<Ñ'<Ñ<Ð<r&   c               ó   € V ^8„  d   QhRR/# rË   r"   )r#   s   "r$   r%   r¥  À  s   € ÷ Uñ U¨4ñ Ur&   c                ó  € ^ RI Hp V! R	RV P                  /VB pVP                  RR4      VP                  RR4      uV n        V n        VP                  RR4      V n        VP                  R4      ;'       g    V P                  V n        R# )
z­Fill api_key / base_url / api_mode / validation_headers from ``resolve_runtime_provider``
for ``new_model``; headers keep their current value when the resolver returns none.r}  rƒ  rZ   rs   r]   r  Úextra_headersNr"   )rŠ  r~  r  rH   rZ   r]   r  r‹  )rO  r  r~  Úrts   &,  r$   Úresolve_runtimeÚ_Switch.resolve_runtimeÀ  sv   € õ 	IÙ%ÑL°4·>±>ÐLÀVÑLˆØ&(§f¡f¨Y¸Ó&;¸R¿V¹VÀJÐPRÓ=SÐ#ˆŒ�d”mØŸ™˜z¨2Ó.ˆŒØ"$§&¡&¨Ó"9×"TÐ"T¸T×=TÑ=TˆÖr&   )rZ   r  r]   r‹  N)rz   r{   r|   r}   r~   r   r  r  r   r!  r  rZ   r]   r  r   r3   r‹  rŒ  r¢  r¨  r¬  rW  r  rµ  r€   r"   r&   r$   r:  r:  ˜  sä   ‡ ñð ƒNØÓØÓØÓØÓØƒOØÓØ"Ó"Ø$Ó$Ø€IˆsÓØ€O�SÓØ€N�CÓØ#(Ð˜DÓ(Ø€N�CÓØ€GˆSÓØ€HˆcÓØ€HˆcÓÙ$°TÔ:Ð˜Ó:Ø$)Ð˜TÓ)Ù¨TÔ2€J�Ó2õkõlð ô=ó ð=÷Uñ Ur&   r:  c               ó    € V ^8„  d   QhRRRR/# ©r   r9  r:  r    úOptional[ModelSwitchResult]r"   )r#   s   "r$   r%   r%   Ê  s   € ÷ *ñ * ð *Ð-Hñ *r&   c                ó°  € \        V P                  V P                  V P                  4      pVfC   V P                  P	                  4       P                  4       R8X  d   \        V P                  4      pVf%   V P                  \        V P                  4      4      # VP                  VP                  uV n        V n        V P                  R8X  d"   V P                  '       g   \        4       V n        \!        V P                  V P                  V P"                  V P                  V P                  4      pV'       d   V P%                  V4      # V P                  '       g¥   VP&                  '       g,   V P%                  RVP                   RV P                   24      # ^ RIHp V! VP&                  4      V n        V P                  '       g9   V P%                  RVP                   RVP&                   R	V P                   24      #  \-        V P                  V P                  V P                  V P                  4      pTe_   Tw  q`n        p\3        Y`P                  T P                  4      \3        T P                  T P                  T P                  4      8X  d   Ypn        R#   \.         d1   pT P                  \1        T4      T P                  R
7      u Rp?# Rp?ii ; i)z¢PATH A (``--provider`` given): resolve the provider, auto-detect a model from a local
endpoint when none was typed, then resolve the alias on the TARGET provider.NrW   r™  rg  zN' has no base URL configured. Specify a model: /model <model-name> --provider )Ú_auto_detect_local_modelzNo model detected on z (z@). Specify the model explicitly: /model <model-name> --provider )r  )r   rí   rî   rï   r:   r;   ra   rU   r¨  r_  rF   rG   r  r  r  rœ  rn  r»   r¬  r]   rŠ  r»  rØ  r   r¹  r½  r   )r9  r¼  Úagg_errr»  Úalias_resultr«  r  rÐ  s   &       r$   Ú_route_explicit_providerr¾  Ê  s`  € ô ! ×!5Ñ!5°r×7HÑ7HÈ"×J]ÑJ]Ó^€DØ‚|˜×,Ñ,×2Ñ2Ó4×:Ñ:Ó<ÀÔHÜ(¨×)<Ñ)<Ó=ˆØ‚|Ø�w‰wÔ0°×1EÑ1EÓFÓGÐGà,0¯G©G°T·Y±YÐ)€BÔ˜Ô)Ø	×Ñ˜UÔ"¨2¯<¯<¨<Ü*Ó,ˆŒä%Ø
×Ñ˜b×0Ñ0°"×2EÑ2EÀr×GXÑGXÐZ\×ZmÑZmóo€GçØ× Ñ  Ó)Ð)à�<�<ˆ<Ø�}�}ˆ}Ø×$Ñ$Ø˜TŸY™Y˜Kð (CØCE×CWÑCWÐBXðZó[ð [õ 	IÙ/°·±Ó>ˆŒØ�|�|ˆ|Ø×$Ñ$Ø'¨¯	©	 {°"°T·]±]°Oð DPØPR×PdÑPdÐOeðgóhð hðZÜ$ R§\¡\°2×3EÑ3EÀr×GXÑGXÐZ\×ZmÑZmÓnˆð ÒØ3?Ñ0ˆœ jô ˜~×/@Ñ/@À"×BUÑBUÓVÜ% b×&8Ñ&8¸"×:KÑ:KÈR×M`ÑM`Óaôbà *ÔÙøô ô ZØ�w‰wÔ/°Ó4Àb×FXÑFXˆwÓYÕYûðZús   È 6J ÊKÊ%%KË
KËKc               ó$   € V ^8„  d   QhRRRRRR/# )r   r9  r:  r¼   r6   r    r¹  r"   )r#   s   "r$   r%   r%   ÷  s"   € ÷ ñ ˜gð ¨Cð Ð4Oñ r&   c           	     ó0  € \        V P                  V P                  V P                  R7      p \	        V P
                  W P                  V P                  4      pTf=   \        T,          pT P                  RT RTP                   RTP                   R24      # Tw  T n        T n        T n        \        P!                  RT P                  T P                  T P                  4       R#   \         d%   pT P                  \        T4      4      u Rp?# Rp?ii ; i)zcStep b: the alias exists but not on the current provider -> try the user's authenticated providers.rd  NzAlias 'z
' maps to r±   z] but no matching model was found in any provider catalog. Try specifying the full model name.z,Alias '%s' resolved via fallback to %s on %s)rò  r»   rî   rï   rý  r¿  r   r¨  r¹  r�   rx   ry   r  r  r   ÚloggerÚdebug)r9  r¼   rj  Úfallback_resultr«  rÐ   s   &&    r$   Ú_route_alias_fallbackrÄ  ÷  sý   € ä-Ø×,Ñ,¸R×=NÑ=NÐac×atÑatô€Fð6Ü1°"·,±,À×HYÑHYÐ[]×[nÑ[nÓoˆð ÒÜ  Õ%ˆØ�w‰wØ�c�U˜* X§_¡_Ð$5°Q°x·±Ð6Gð H2ð 3ó4ð 	4ð ;JÑ7€BÔ˜œ bÔ&7Ü
‡L�LØ6¸×8IÑ8IÈ2Ï<É<ÐY[×YkÑYkômáøô ô 6Ø�w‰wÔ/°Ó4Ó5Õ5ûð6ús   ®+C& Ã&DÃ1DÄ
DÄDc               ó    € V ^8„  d   QhRRRR/# ©r   r9  r:  r    rÌ   r"   )r#   s   "r$   r%   r%     s   € ÷ Vñ V 7ð V¨tñ Vr&   c                óJ  € V P                   pVP                  R4      p\        V P                  4      P	                  4       P                  4       pV^ 8:  g&   RV9   g   VP                  R4      '       g   VR8X  d   R# VRV P	                  4       P                  4       pW^,           R P	                  4       pV'       d	   V'       g   R# \        V P                  4      '       g   \        W@4      '       g   R# V RV 2V n	        \        P                  RWP                  4       R# )a¥  Step c: ``vendor:model`` -> ``vendor/model``. Only without a slash: with one, the colon is
a variant tag (:free, :extended, :fast) that must be preserved.

On an aggregator every ``left:right`` is a slug. Elsewhere the colon is converted only when
``left`` names a provider Hermes knows, so ``/model alibaba:qwen3.6-plus`` routes like
``alibaba/qwen3.6-plus`` (#9748) while Ollama-style tags (``qwen3.5:4b``) stay intact.Ú:r±   rW   rT  Nz(Converted vendor:model '%s' to slug '%s')r¿  Úfindr6   r»   r:   r;   rg   r   Ú_names_known_providerr  rÁ  rÂ  )r9  r¿  Ú	colon_posÚcur_normÚleftÚrights   &     r$   Ú_convert_vendor_colon_slugrÏ    sç   € ð —‘€IØ—‘˜sÓ#€IÜ�2×&Ñ&Ó'×-Ñ-Ó/×5Ñ5Ó7€HØ�A„~˜ 	Ô)¨X×-@Ñ-@À×-JÒ-JÈhÐZbÔNbÙØ�Z�iÐ ×&Ñ&Ó(×.Ñ.Ó0€DØ !•m�nÐ%×+Ñ+Ó-€Eß—uÙÜ˜×,Ñ,×-Ò-Ô6KÈD×6UÒ6UÙØ�V˜1˜U˜GÐ$€B„LÜ
‡L�LÐ;¸YÏÉÖUr&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rG   r6   r9  r:  r    rK   r"   )r#   s   "r$   r%   r%   "  s!   € ÷ ñ  ð ¨ð °Tñ r&   c                ó”   € ^ RI Hp \        WP                  VP                  4      e   R#  V! V RR7      RJ#   \
         d     R# i ; i)zSWhether ``name`` is a built-in provider id/alias or a provider the user configured.)Úget_providerNTF©Úallow_network)r  rÒ  r   rî   rï   r¶   )rG   r9  rÒ  s   && r$   rÊ  rÊ  "  sJ   € å1Ü˜T×#4Ñ#4°b×6IÑ6IÓJÒVÙðÙ˜D°Ô6¸dÐBÐBøÜô Úðús   ¬8 ¸AÁAc               ó    € V ^8„  d   QhRRRR/# )r   r9  r:  r    z"Optional[ModelSwitchResult] | boolr"   )r#   s   "r$   r%   r%   -  s   € ÷ ñ  7ð Ð/Qñ r&   c                ó|  € \        V P                  V P                  V P                  4      pV'       g   R# \	        W4      pVe   W,          V n        R# \        V4      p\        V4      ^8”  d2   V P                  RV P                   RRP                  V4       R24      # V^ ,          V n	        WP                  ,          V n        \        P                  RV P                  V P                  4       \        V P                  \        4      '       d-   V P                  V P                  9   d   V P                  V n        R# )a-  Step d.5: a model declared in user/custom provider config routes there BEFORE
detect_provider_for_model() guesses from static catalogs and before a soft-accepting current
provider (openai-codex) can swallow it as an unknown hidden model. Returns a failure result,
``True`` when routed, else ``False``.FTr³  z0' is declared by multiple configured providers (re  z<). Re-run with --provider <slug> to choose which one to use.z/Configured-provider detection routed '%s' to %s)r"  r  rî   rï   r@  Úsortedrh   r¨  r6  r  rÁ  rÂ  r2   r3   rí   )r9  r;  Úcurrent_slugÚmatch_slugss   &   r$   Ú_route_configured_providerrÚ  -  s
  € ô
 /¨r¯|©|¸R×=NÑ=NÐPR×PcÑPcÓd€KßÙÜ*¨2Ó;€LØÒØ"Õ0ˆŒÙÜ˜Ó%€KÜ
ˆ;Ó˜!ÔØ�w‰wØ�—‘ˆ~ð ØŸ)™) KÓ0Ð1ð 2<ð=ó>ð 	>ð % Q�€BÔØ×1Ñ1Õ2€B„LÜ
‡L�LÐBÀBÇLÁLÐRT×RdÑRdÔeô �"×#Ñ#¤T×*Ò*¨r×/AÑ/AÀR×EVÑEVÔ/VØ!×1Ñ1ˆÔÙr&   c               ó    € V ^8„  d   QhRRRR/# r¸  r"   )r#   s   "r$   r%   r%   I  s   € ÷ =ñ = ð =Ð,Gñ =r&   c                óV  € ^ RI Hp V P                  V P                  r2 ^ RIHp ^ RIHpHp T! T! V! 4       P                  R4      ;'       g    / 4      V4      pV'       d   RVRuV n        V n        V n        MÒ \        W#V P                  V P                   4      pTeM   Tw  T n        T n        T n        \(        P+                  RT P                  T P                  T P                  4       M`TP-                  4       P/                  4       \0        9   d/   \3        YP-                  4       P/                  4       4      p
T
e   T
# M\5        T 4       Rp\7        V P                  4      '       dT   V P                  '       gB   \9        V P                  4      pV'       d%   \;        V P                  V4      pVe   VR	uV n        pV P                  '       g   V'       g   V P                  V8w  d   R# VR
8X  dP   ^ RIHpH p V! V PB                  4      '       d0   V P                  V8w  d   V P%                  V P                   R24      # \E        V 4      p\G        V\H        4      '       d   V# VR9   ;'       g<    VPK                  R4      ;'       g#    \M        V PB                  ;'       g    R4      R9   pV'       g3   V'       g+   V! V P                  V4      pV'       d   Vw  V n        V n        R#   \         d    Rp EL›i ; i  \"         d%   p	T P%                  \'        T	4      4      u Rp	?	# Rp	?	ii ; i)zúPATH B (no ``--provider``): MoA preset / alias on the current provider (a) -> alias
fallback (b) or ``vendor:model`` conversion (c) -> aggregator catalog search (d) ->
configured-provider match (d.5) -> detect_provider_for_model() as last resort (e).)Údetect_provider_for_modelr­   )Úexact_moa_preset_namer˜  r™  Nrs   zAlias '%s' resolved to %s on %sFTrû  )ÚGUEST_MODELÚroute_is_welcome_hostz_ needs a Nous account or an API key. Use /login to sign in, or /model to pick another provider.r  >   ÚlocalrW   )Ú	localhostú	127.0.0.1)'r  rÝ  r¿  r»   r³   r®   r›  rÞ  r˜  rH   r¶   r  r  r   rØ  rî   rï   r   r¨  r¹  rÁ  rÂ  r:   r;   r�   rÄ  rÏ  r   r   ru  Úhermes_cli.anon_authrß  rà  rU   rÚ  r2   r  rg   r   )r9  rÝ  r¿  r»   r®   rÞ  r˜  Ú	moa_matchr½  r«  r¨  Úresolved_in_current_catalogrÕ  Úmatchedrß  rà  Úconfig_routedÚ	is_customÚdetecteds   &                  r$   Ú_route_from_model_inputrë  I  sÂ  € õ <Ø"$§,¡,°×0CÑ0CÐðÝ1ßUÙ)Ñ*>¹{»}×?PÑ?PÐQVÓ?W×?]Ð?]Ð[]Ó*^Ð`iÓjˆ	÷ Ø>CÀYÐPRÐ;ˆÔ˜BœL¨"Õ*;ð	:Ü(¨Àb×FWÑFWÐY[×YlÑYlÓmˆLð Ò#ØBNÑ?ˆBÔ ¤¨bÔ.?Ü�L‰LÐ:¸B×<MÑ<MÈrÏ|É|Ð]_×]oÑ]oÕpØ�_‰_Ó×$Ñ$Ó&¬-Ô7Ü(¨¯_©_Ó->×-DÑ-DÓ-FÓGˆDØÒØ�ð  ô ' rÔ*ð
 #(ÐÜ�R×'Ñ'×(Ò(°×1B×1BÐ1BÜ& r×'9Ñ'9Ó:ˆßÜ/°·±¸gÓFˆGØÒ"Ø<CÀTÐ9�”Ð9ð 
××Ð×7¸2×;MÑ;MÐQaÔ;aÙØ˜6Ô!÷ 	LÙ  ×!4Ñ!4×5Ò5¸"¿,¹,È+Ô:UØ—7‘7Ø—<‘<�.ð !Mð MóNð Nô /¨rÓ2€MÜ�-Ô!2×3Ò3ØÐàÐ/Ñ/÷ 	Vð 	VÐ3C×3NÑ3NÈyÓ3Y÷ 	Vð 	VÜ˜R×0Ñ0×6Ð6°BÓ7Ð;UÑUð ÷ §Ù,¨R¯\©\Ð;KÓLˆßØ/7Ñ,ˆBÔ ¤Ùøôg ô Ø‹	ðûô #ô 	:Ø—7‘7Ô3°CÓ8Ó9Õ9ûð	:ús/   Ÿ;K% Á:!K9 Ë%K6Ë5K6Ë9L(ÌL#ÌL(Ì#L(c               ó    € V ^8„  d   QhRRRR/# )r   r9  r:  r    r6   r"   )r#   s   "r$   r%   r%   ‰  s   € ÷ ñ ˜wð ¨3ñ r&   c                ó2  € \        V P                  4      pV P                  R 8X  d   V P                  '       d   RpV P                  P                  R4      '       d<   \	        V P                  V P
                  V P                  4      pVe   VP                  pV# )rW   rX   r  )r   r  rU   rg   r   rî   rï   rG   )r9  ÚlabelÚcustom_pdefs   &  r$   Ú_switch_provider_labelrð  ‰  s~   € Ü�b×(Ñ(Ó)€EØ	×Ñ˜XÔ%¨"×*=×*=Ð*=Ø!ˆØ	×Ñ×$Ñ$ Y×/Ò/Ü+¨B×,>Ñ,>À×@QÑ@QÐSU×SfÑSfÓgˆØÒ"Ø×$Ñ$ˆEØ€Lr&   c               ó    € V ^8„  d   QhRRRR/# r¸  r"   )r#   s   "r$   r%   r%   ”  s   € ÷ ;ñ ; Wð ;Ð1Lñ ;r&   c                óº  € RpV P                   P                  4       P                  4       pV P                   '       dP   V P                  '       d>   ^ RIHp V! W P                  4      ;'       g    V! V P                  V P                  4      pVeû   VP                  '       dé   V P                  P                  V4      ;'       g0    V P                  P                  V P                  4      ;'       g    / p\        V\        4      p\        V4      V n         T P                  V P                  T;'       g    RVP                  R7       V P                  ;'       g    TV P                  ;'       g    VP                  uV n        V n        R# V P                  R8X  dÜ   V P"                  '       dÊ   V P$                  V P"                  rvV P&                  R8w  dm   \)        \        4      ;_uu_ 4        V P                  RR7       RRR4       V P                  '       d)   \+        V 4      '       g   V P                  V P                  rvWguV n        V n        \-        V P                  V P                  4      V n        R# ^ RIHp V P2                  '       d    \4        P                  V P2                  4      MRp	V	e%   V! V P                  4      '       d   V	P                  MRp
 T P                  V P                  T
;'       g    RR7       R#   \         d$    YQP                  RuT n        T n        T n         R# i ; i  + '       g   i     EL>; i  \         dˆ   pT P                  P                  4       P                  4       \6        9   d    T P9                  \;        T4      4      u Rp?# T P9                  T P<                   R	T P                   R
T 24      u Rp?# Rp?ii ; i)aC  Credentials when the provider changed or ``--provider`` was given.

``providers.<name>`` blocks carry their own base_url + transport + key reference;
resolve_runtime_provider() resolves by provider NAME and would re-resolve a block named
"openai" from scratch (or hop to an aggregator), so use the pdef's endpoint directly.N)Úresolve_user_provider)r€  r�  r‚  rs   rW   ©r€  )Ú_resolves_to_custom)r€  r‚  zW is not connected: no API key or login was found for it. Add one with `hermes auth add z6`, or pick a connected provider in /model.
  Details: )rí   r:   r;   rî   r  ró  r  r]   rH   rO  rÚ   Ú_extra_headers_from_configr‹  rµ  rZ   r¶   r  rU   rŸ  r»   r   Ú _fell_back_to_openrouter_defaultr   rŠ  rõ  r   r¨   r	   r¬  r6   r  )r9  Ú	user_pdefrh  ró  ÚucfgÚukeyr¼   r(  rõ  rÑ  Ú	alias_urlr  s   &           r$   Ú_creds_for_switched_providerrü  ”  s2  € ð €IØ×(Ñ(×.Ñ.Ó0×6Ñ6Ó8€MØ	××Ð × 1× 1Ð 1Ý>Ù*¨=×:KÑ:KÓL÷ Uð UÙ-¨b×.@Ñ.@À"×BSÑBSÓTð 	àÒ ×!3×!3Ð!3Ø× Ñ ×$Ñ$ ]Ó3×fÐf°r×7HÑ7H×7LÑ7LÈR×M_ÑM_Ó7`×fÐfÐdfˆä$ T¬?Ó;ˆÜ :¸4Ó @ˆÔð	PØ×ÑØ×,Ñ,¸t¿|¸|ÀtÐ_h×_qÑ_qð ô sà&(§j¡j×&8Ð&8°D¸"¿+¹+×:[Ð:[È×I[ÑI[Ð#ˆBŒJ˜œñN ðI 
×	Ñ	˜xÔ	'¨B×,?×,?Ð,?ð ×%Ñ% r×':Ñ':ˆSØ×Ñ (Ô*Üœ)×$Õ$Ø×"Ñ"¨XÐ"Ô6÷ %à�{�{ˆ{Ô#CÀB×#GÒ#GØŸ:™: r§{¡{�SØ"%ÐˆŒ
�B”KÜ(¨×);Ñ);¸R¿[¹[ÓIˆŒñ, õ 	DØ68×6G×6GÐ6GŒ^×Ñ × 1Ñ 1Ô2ÈTˆØ#%¢>Ñ6IÈ"×J\ÑJ\×6]Ò6]�B—K’KÐcgˆ	ð
	#Ø×Ñ¨×);Ñ);Èy×O`ÐO`Ð\`ÐÔañ øôM ô 	PØ37×9KÑ9KÈRÐ0ˆBŒJ˜œ R¥[ñJ ðM	Pú÷ %×$Ð$ûô$ ô 	#Ø×!Ñ!×'Ñ'Ó)×/Ñ/Ó1Ô5EÔEð ×(Ñ(¬¨Q«Ó0Õ0Ø×$Ñ$Ø×$Ñ$Ð%ð &$Ø$&×$6Ñ$6Ð#7ð 8Ø˜Sð"ó#õ #ûð	#úsa   ÄL Ä4%L ÅL Å/L Ç,L4ËM Ë9M Ì*L1Ì0L1Ì4M	ÍOÍA
OÎOÎ#,OÏOÏOc               ó    € V ^8„  d   QhRRRR/# rÆ  r"   )r#   s   "r$   r%   r%   Ò  s   € ÷ )Oñ )O Gð )O°ñ )Or&   c                óÂ  € ^ RI HpHp Rp/ pV P                  R8X  dv   V P                  '       dd    ^ RI Hp V! 4       p\        4       w  rgV'       d   V! V P                  V4      '       g
   / pRV n        V! V P                  V P                  VR7      pV'       dZ   V P                  ;'       g    RV n        V P                  V n        \!        V P                  V P                  4      V n        W@n        R	#  V P'                  V P                  R7       V P                  R
9   d„   V P                  '       dp   V P                  '       d   \+        V 4      '       dK   V P                  V P                  uV n        V n        \!        V P                  V P                  4      V n        R	# R	# R	# R	#   \        \        \        \        \        3 d    Rp EL9i ; i  \(         d     LÌi ; i)zìCredentials when staying on the current provider. Mid-session ``/model <name>`` on a local
Ollama-compatible endpoint keeps the endpoint in use; re-resolving bare ``custom`` from config
can fall through to an unrelated default provider.)Ú_get_ollama_request_headersr|  FrW   )Ú should_use_ollama_native_catalogT)Úheadersr  rô  N>   rá  rW   )r‰  rÿ  r|  r»   rU   r   rU  rŒ  ÚImportErrorrÇ   ÚRuntimeErrorÚ	TypeErrorr—  rŸ  rZ   r]   r   r  r‹  rµ  r¶   r÷  )r9  rÿ  r|  Úkeep_current_ollama_endpointÚollama_headersr   ré   Úconfigured_ollama_bases   &       r$   Ú_creds_for_current_providerr  Ò  s–  € ÷ ^Ø#(Ð Ø%'€NØ	×Ñ˜hÔ&¨2×+>×+>Ð+>ð	1ÝPÙ8Ó:ˆNÜ(?Ó(AÑ%ˆA÷ *Ñ1IÈ"×J]ÑJ]Ð_u×1vÒ1vØ!#�Ø-1�Ô*Ù+KØ×#Ñ# R×%8Ñ%8À.ô,RÐ(÷ $Ø×'Ñ'×<Ð<Ð+<ˆŒ
Ø×)Ñ)ˆŒÜ(¨×)<Ñ)<¸b¿k¹kÓJˆŒØ .Öð	Ø×Ñ¨×)<Ñ)<ÐÔ=ð ×ÑÐ#6Ô6¸2×;N×;NÐ;NØ—[—[�[Ô$DÀR×$HÒ$Hà&(×&9Ñ&9¸2×;MÑ;MÐ#ˆBŒK˜œÜ,¨R×-@Ñ-@À"Ç+Á+ÓNˆBŽKñ %Iñ <OÑ6øô% œW¤l´I¼zÐJô 	1Ø+0Ó(ð	1ûô ô 	Ùð	ús)   ±9F' Á+(F' Ã5G Æ'"GÇGÇGÇGc               ó    € V ^8„  d   QhRRRR/# )r   r9  r:  r    rK   r"   )r#   s   "r$   r%   r%   þ  s   € ÷ 	Qñ 	Q¨ð 	Q°Tñ 	Qr&   c                óü   € \        4       pV'       d3   V P                  P                  R4      V8X  d   \        4       '       g   R# \	        V P                  R4      ;'       d    \	        V P
                  R4      '       * # )uI  The bare-``custom`` resolver ended on an OpenRouter endpoint that is not a custom endpoint
the user configured: the built-in default host, or the ``OPENROUTER_BASE_URL`` mirror â€” the
credential ladder's last rung (#10622), which ``provider: custom`` reaches only when no
``CUSTOM_BASE_URL`` / trusted ``model.base_url`` exists.r±   Tzopenrouter.ai)Ú_openrouter_mirror_base_urlr]   r–  Ú_custom_endpoint_sourcer   rU   )r9  Úmirrors   & r$   r÷  r÷  þ  sd   € ô
 )Ó*€Fß�"—+‘+×$Ñ$ SÓ)¨VÔ3Ô<S×<UÒ<UÙÜ! "§+¡+¨Ó?÷ Pð PÜ)¨"×*=Ñ*=¸ÓOÔOðQr&   c               ó   € V ^8„  d   QhRR/# rK  r"   )r#   s   "r$   r%   r%   
  s   € ÷ ñ  ñ r&   c                 ó  € ^ RI Hp   V ! RR4      ;'       g    RP                  4       pV'       d   V# ^ RIHpHp V! 4       ;'       g    / p\        VP                  R4      \        4      '       d   VP                  R4      MRp\        VP                  R4      \        4      '       d   VP                  R4      MRpT;'       g    RP                  4       pV'       d   V! WV4      '       d   V# R#   \         d     R# i ; i)af  The endpoint the credential ladder prefers over its OpenRouter rung for bare ``custom``:
``CUSTOM_BASE_URL``, else the config's ``model.base_url`` when that config backs bare custom.
Non-empty means a resolved URL matching the mirror came from a configured custom endpoint (two
env vars pointed at one proxy), so the mirror guard must not call it a fallback.©Úget_secret_strÚCUSTOM_BASE_URLrs   )Ú,_config_base_url_trustworthy_for_bare_customÚ_get_model_configr]   r¡   )
Úagent.secret_scoper  r:   rŠ  r  r  r2   rH   r6   r¶   )r  Úenv_urlr  r  r@  Úbaser¡   s          r$   r  r  
  sÕ   € õ
 2ðÙ!Ð"3°RÓ8×>Ð>¸B×EÑEÓGˆßØˆN÷	Má%Ó'×-Ð-¨2ˆ	Ü,6°y·}±}ÀZÓ7PÔRU×,VÒ,Vˆy�}‰}˜ZÔ(Ð\^ˆÜ0:¸9¿=¹=ÈÓ;TÔVY×0ZÒ0Z�9—=‘= Ô,Ð`bˆØ—
�
˜×!Ñ!Ó#ˆßÑ LÈT× \Ò \ˆtÐdÐbdÐdøÜô Úðús9   ˆC0 ˜C0 ±C0 ³C0 Á	A;C0 ÃC0 ÃC0 Ã.C0 Ã0C?Ã>C?c               ó   € V ^8„  d   QhRR/# rK  r"   )r#   s   "r$   r%   r%     s   € ÷ 	ñ 	 Sñ 	r&   c                 ó”   € ^ RI Hp   V ! RR4      ;'       g    RP                  4       P                  R4      #   \         d     R# i ; i)ur  ``OPENROUTER_BASE_URL``, read the way the resolver reads it (env, or the profile's secret
scope). A guard read, not a credential fetch: a read that fails â€” unscoped under multiplexing â€”
must leave the mirror undetected so its caller keeps the session endpoint, rather than raising
out of ``switch_model`` where the resolver's own read of the same name is suppressed.r  ÚOPENROUTER_BASE_URLrs   r±   )r  r  r:   r–  r¶   r  s    r$   r  r    sI   € õ
 2ðÙÐ4°bÓ9×?Ð?¸R×FÑFÓH×OÑOÐPSÓTÐTøÜô Úðús   ˆ8 ˜8 ¸AÁAc               ó    € V ^8„  d   QhRRRR/# r¸  r"   )r#   s   "r$   r%   r%   +  s   € ÷ ñ  Gð Ð0Kñ r&   c                óÜ  € \        V 4      V n        V P                  V P                  uV n        V n        V P                  '       g   V P                  '       d   \        V 4      pVe   V# M\        V 4       V P                  '       dR   \        4        \        P                  V P                  4      pVe%   VP
                  '       d   \        W4       RV n        ^ RIHp V! V P$                  V P
                  4      '       d   RM\'        V P
                  4      pVe   V P(                  R8w  d   W@n        V P(                  ;'       g!    \+        V P$                  V P
                  4      V n        R# )z‡COMMON PATH part 1: credentials, direct-alias endpoint override, and the api_mode for the
final (provider, base_url) before validation.NT)Úis_actual_routeÚchat_completionsÚcodex_app_server)rð  r  rŸ  rU   rZ   r]   r  rí   rü  r  r   rÒ   r¨   rH   r•  r!  r  r  r  r   r  r   )r9  r¨  rÑ  r  Úmandated_modes   &    r$   Ú_resolve_switch_credentialsr!  +  s*  € ô /¨rÓ2€BÔØ ×0Ñ0°"×2EÑ2EÐ€B„J�”Ø	××Ð˜b×2×2Ð2Ü+¨BÓ/ˆØÒØˆKð ô 	$ BÔ'ð 
××ÐÜÔ Ü×Ñ × 1Ñ 1Ó2ˆØŠ>˜bŸkŸk˜kÜ(¨Ô0Ø(,ˆBÔ%õ 5Ù*9¸"×:LÑ:LÈbÏkÉk×*ZÒ*ZÑ&Ô`vÐwy÷  xCñ  xCó  aD€MØÒ  R§[¡[Ð4FÔ%FØ#ŒØ—+‘+×TÐTÔ!3°B×4FÑ4FÈÏÉÓ!T€B„KÙr&   c               ó    € V ^8„  d   QhRRRR/# r¸  r"   )r#   s   "r$   r%   r%   K  s   € ÷ 3ñ 3˜ð 3Ð%@ñ 3r&   c                ó„  € ^ RI Hp ^ RIHp \	        V P
                  V P                  V P                  4      V n        \        V P
                  V P                  4      V n        ^ RI	H
p V! V P
                  4      '       dB   V P                  RV P
                   R2V P
                  V P                  V P                  R7      # V P                  P                  4       P                  4       R8X  d1   V P                  '       d   / MV P                   ;'       g    V! 4       pMqV P                   ;'       g^    V P"                  '       dJ   V P                  V P"                  9   d/   \%        V P"                  P'                  V P                  4      4      MRpV P                  pVP                  4       P)                  R	4      '       gN   \+        WPP"                  V P                  4      pVe*   VP,                  R
8X  d   VP.                  '       g   MRV 2p T! V P
                  YPP0                  V P.                  V P2                  ;'       g    RVR7      pVP'                  R4      '       g¥   \7        V P
                  V P                  V P.                  V P"                  V P                  4      '       gD   V P                  VP'                  RR4      V P
                  V P                  V P                  R7      # RRRRRRRVP'                  RR4      /pWpn        R#   \4         d%   pRRRRRRRRT P
                   RT 2/p Rp?LíRp?ii ; i)zŽCOMMON PATH part 2: normalize the model name for the target provider, validate it, and
accept config-declared models the remote catalog lacks.)rÿ  )Úvalidate_requested_model)Úis_known_non_chat_modelÚ`zq` is a generation model and cannot be used for chat. Pick a chat model, or use image generation for image models.)r  r  r  rT  NrW   zuser-configrs   r  )rZ   r]   r  r  ÚacceptedFÚpersistÚ
recognizedrZ  zCould not validate `z`: zInvalid modelT)r‰  rÿ  Úhermes_cli.models_validater$  rG  r  r  rï   r   Úhermes_cli.chat_catalogr%  r¨  r  r:   r;   rŒ  r‹  rî   rö  rH   rg   r   r_   r]   rZ   r  r¶   ry  r¢  )	r9  rÿ  r$  r%  r  Úvalidate_asr¼  r¢  r  s	   &        r$   Ú_validate_switchr-  K  sÏ  € õ DÝCÜ1°"·,±,À×@RÑ@RÐTV×TgÑTgÓh€B„LÜ/°·±¸b×>PÑ>PÓQ€B„Lå?Ù˜rŸ|™|×,Ò,Ø�w‰wØ�—‘ˆ~ð Kð Kà—l‘l°B×4FÑ4FØ×,Ñ,ð	 ó 
ð 	
ð 
×Ñ×ÑÓ!×'Ñ'Ó)¨XÔ5Ø×2×2Ð2‘"¸×9NÑ9N×9oÐ9oÑRmÓRo‰à×'Ñ'÷ Xð Xà× × Ð  R×%7Ñ%7¸2×;LÑ;LÔ%Lô ' r×'8Ñ'8×'<Ñ'<¸R×=OÑ=OÓ'PÔQØRVð 	ð ×$Ñ$€KØ×ÑÓ×)Ñ)¨(×3Ò3Ü$ [×2CÑ2CÀR×EXÑEXÓYˆð Ò §¡¨}Ô <À$Ç-Ç-À-ÐSUØ# K =Ð1ˆKðNÙ-Ø�L‰L˜+¯z©zÀBÇKÁKØ—[‘[×(Ð( D°'ô;ˆ
ð �>‰>˜*×%Ò%Ü%Ø—‘˜b×0Ñ0°"·+±+¸r×?PÑ?PÐRT×ReÑRe÷gò gà—7‘7Ø—‘˜y¨/Ó:ØŸ,™,¸×8JÑ8JÐ[]×[lÑ[lð ó nð nð ! $¨	°4¸ÀuÈiÐYc×YgÑYgÐhqÐsuÓYvÐwˆ
Ø„MÙøô ô NØ  %¨°E¸<ÈØÐ#7¸¿¹°~ÀSÈÈÐ!LðN�
ûðNús   È5L É	L ÌL?ÌL:Ì:L?c               ó(   € V ^8„  d   QhRRRRRRRR/# ©r   r¡   r6   r    rZ   r    r"   )r#   s   "r$   r%   r%   �  s(   € ÷ :ñ : ð :¨Cð :¸#ð :À#ñ :r&   c                ó    € ^ RI Hp V! WR7      # )rR  )Úcopilot_model_api_mode)rZ   )r  r1  )r¡   r    rZ   r1  s   &&& r$   Ú_copilot_api_moder2  �  s   € Ý8Ù! %Ô9Ð9r&   c               ó(   € V ^8„  d   QhRRRRRRRR/# r/  r"   )r#   s   "r$   r%   r%   †  s(   € ÷ 
4ñ 
4 ð 
4¨Sð 
4¸3ð 
4À3ñ 
4r&   c                ó   € ^ RI Hp V! W4      # )rR  )Úopencode_model_api_mode)r  r5  )r¡   r    rZ   r5  s   &&& r$   Ú_opencode_api_moder6  †  s   € õ :Ù" 8Ó3Ð3r&   c               ó(   € V ^8„  d   QhRRRRRRRR/# r/  r"   )r#   s   "r$   r%   r%   “  s(   € ÷  ñ  ˜Sð  ¨ð  °sð  ¸sñ  r&   c                ó   € ^ RI Hp V! V4      # )rR  )Únous_api_mode)r  r9  )r¡   r    rZ   r9  s   &&& r$   Ú_nous_api_moder:  “  s   € õ 3Ù˜ÓÐr&   údict[str, Any]Ú_PROVIDER_API_MODE_OVERRIDESc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r¡   r6   r    rZ   r    r0  r"   )r#   s   "r$   r%   r%   £  s.   € ÷ Kñ K Sð K°ð K¸sð KÈMñ Kr&   c                óØ   € ^ RI Hp \        T ;'       g    R4      P                  4       P	                  4       p\
        P                  V! V4      ;'       g    T4      pVe
   V! WAV4      # R# )uŒ  api_mode re-derived from the FINAL model for providers that serve several wire formats behind one
endpoint (OpenCode Zen/Go and custom providers extending a family slug, Copilot, Nous); None when the
provider's wire is fixed by its endpoint. A persisted api_mode from an earlier model of such a provider
is never authoritative â€” resume paths must call this instead of honoring the row (#96066).)Úopencode_provider_familyrs   N)r  r?  r6   r:   r;   r<  rH   )r¡   r    rZ   r?  r¼   Úoverrides   &&&   r$   Úmodel_derived_api_moderA  £  s_   € õ
 ;Ü
ˆh�nˆn˜"Ó
×
#Ñ
#Ó
%×
+Ñ
+Ó
-€CÜ+×/Ñ/Ñ0HÈÓ0M×0TÐ0TÐQTÓU€HØ,4Ò,@‰8�C Ó(ÐJÀdÐJr&   c               ó    € V ^8„  d   QhRRRR/# )r   r9  r:  r    r  r"   )r#   s   "r$   r%   r%   ®  s   € ÷ *iñ *i˜Wð *iÐ):ñ *ir&   c                óÜ  € \        V P                  V P                  V P                  4      pVe   Wn        V P                  '       g2   \        V P                  V P                  V P                  R7      V n        ^ RIHpH	p V! V P                  4      eN   \        V P                  \        4      '       d.   V! V P                  V P                  V P                  4      V n        \        V P                  V P                  RR7      p^ RIHp V! V P                  V P                  V P                  V P                  P                  4       P!                  4       R8H  R7      p\#        V P                  V P                  RR7      pV P$                  P'                  R	4      \)        V P                  4      3 Uu. uF  qˆ'       g   K  VNK  	  p	p^ R
IHp
 V
! V P                  V P                  RR7      ;'       g    RpRp ^ RIHpHp V! V P                  4      pV'       d   V! V4      ;'       g    RMRp\7        R / RRbRV P                  bRV P                  bRV P8                  bRV P                  bRV P                  bRV P                  bR\;        T;'       g    / 4      bRV	'       d   RP=                  V	4      MRbRVbRV P>                  bRV P@                  bRVbRVPC                  4        UUu/ uF9  w  pp\        V\        4      '       g   K  \        V\D        4      '       g   K6  VVbK;  	  uppbRVbRV PF                  bRV PH                  b # u upi   \4         d    Rp EL5i ; iu uppi )!zJCOMMON PATH part 3: final api_mode / base_url shaping, metadata, warnings.N)r    )Únormalize_opencode_base_urlr?  TrÓ  )Ú&resolve_native_compaction_capabilitieszopenai-codex)r    r]   r¡   Úis_codex_backendrZ  )Úlarge_model_notice)Úfetchrs   )Ú_get_named_custom_providerÚ"_custom_provider_request_overridesr  r  r  r  rZ   r]   r  r  r  z | r  r  r  r  r  r  r   r!  r"   )%rA  r  r  rZ   r  r   r]   r  rD  r?  r2   r6   r   Úagent.native_compactionrE  r:   r;   r   r¢  rH   ru   Úhermes_cli.model_picker_usagerG  rŠ  rI  rJ  r¶   r  r  r3   r6  r  r   r´   rK   r   r!  )r9  ÚderivedrD  r?  r  rE  r  r  ÚwÚwarningsrG  r  r  rI  rJ  Ú	cp_for_ror,   rà  s   &                 r$   Ú_build_switch_resultrQ  ®  s)  € ä$ R×%7Ñ%7¸¿¹ÀrÇzÁzÓR€GØÒØŒØ�;�;ˆ;Ü(¨×);Ñ);¸R¿[¹[ÐPR×P\ÑP\Ô]ˆŒ÷
 XÙ × 2Ñ 2Ó3Ò?ÄJÈrÏ{É{Ô\_×D`ÒD`Ù1°"×2DÑ2DÀbÇkÁkÐSU×S^ÑS^Ó_ˆŒä)¨"×*<Ñ*<¸b¿l¹lÐZ^Ô_€LÝNÙAØ�l‰l R§[¡[¸2×;MÑ;MØ×+Ñ+×1Ñ1Ó3×9Ñ9Ó;¸~ÑMôOÐô   × 2Ñ 2°B·L±LÐPTÔU€JàŸM™M×-Ñ-¨iÓ8Ô:UÐVX×VbÑVbÓ:cÑdÓjÑd�aÓhi—�Ñd€HÐjÝ@Ù% b§l¡l°B×4FÑ4FÈdÔS×YÐYÐWY€Lð Ðð!ßnÙ.¨r×/AÑ/AÓBˆ	ßU^Ñ>¸yÓI×QÐQÈTøÐdhÐô ò iÙðiØ "§¢ðiØ>@×>PÒ>Pðià×,Ò,ðià68·j²jðiàKMÏ;Ê;ðiàac×alÒalðiô Ð0×6Ð6°BÔ7ði÷ bjÈÏÉÐT\ÔI]Ðoqøðiñ "ð	ið 35×2CÒ2Cð	ið Y[×XiÒXið	iñ yEð	ið 2×7Ñ7Ô9ôiÙ9‘T�Q˜¼ZÈÌ3×=OŒDÔT^Ð_`Ôbf×TgŒDˆAˆqŠDÑ9óiðiñ ðið *,¯ªðið OQ×NgÒNgðið iùò køô ô !Ø Óð!üóis<   Æ1	MÆ?MÇ9!M ÈM È*M Ë-M(ÌM(Ì%M(ÍM%Í$M%c               ó@   € V ^8„  d   QhRRRRRRRRRRRRR	RR
RRRRR/
# )r   r¿  r6   r»   rž  rU   rŸ  r   rK   rí   rî   rë  rï   rì  r    r  r"   )r#   s   "r$   r%   r%   Û  se   € ÷ $ñ $Øð$Ø&)ð$Ø:=ð$ØQTð$àð$à*.ð$àKNð$ð  ð$ð ;Fð$ð Rcñ$r&   c	                óÊ   € \        WVW4VWgVV P                  4       VR7      p	V'       d   \        M\        p
V
\        \
        3 F  pV! V	4      pVf   K  Vu # 	  \        V	4      # )ak  Core model-switching pipeline shared between CLI and gateway.

Route (PATH A with ``--provider``, else PATH B) -> credentials -> validation -> result; each
step returns a failure :class:`ModelSwitchResult` to stop the chain, or ``None`` to continue.
``user_providers`` / ``custom_providers`` are the config.yaml ``providers:`` dict and
``custom_providers:`` list.)r¿  r»   rž  rU   rŸ  r   rí   rî   rï   r  r  )r:  r:   r¾  rë  r!  r-  rQ  )r¿  r»   rž  rU   rŸ  r   rí   rî   rï   r9  Úrouter˜   r¨  s   &&&&&&&&&    r$   Úswitch_modelrU  Û  so   € ô 
ØÈmØ)ÐV_Ø+Ð]mØ—/‘/Ó#Ð5Eô	
G€B÷
 ):Õ$Ô?V€EØÔ3Ô5EÓFˆÙ�B‹xˆØÔØŠKñ Gô   Ó#Ð#r&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úresultr  Úcurrent_model_cfgr   r    r;  r"   )r#   s   "r$   r%   r%   ò  s$   € ÷ %ñ %Ð+<ð %ÐQTð %ÐYgñ %r&   c           	     óþ  € \        V\        4      '       d   TM/ pRV P                  RV P                  RV P                  ;'       g    RRV P
                  ;'       g    R/pRV9   dƒ   ^ RIHp T! VP                  R4      ;'       g    VP                  R4      V P                  VP                  R4      V P                  VP                  R4      V P                  4      '       d   RVR&   \        V P                  ;'       g    R	4      P                  4       P                  4       p\        W 4      pVP                  R
4      '       d	   V'       d   RR.M. pV'       d   VRR.,          pV F  pW‚9   g   K  RW8&   K  	  V# )u�  The ONE config.yaml shape a persisted model selection produces, as ``model.<key>`` -> value
(``None`` = clear). ``current_model_cfg`` is the on-disk ``model:`` block (raw).

base_url/api_mode are freshly resolved for the target route, so they are always synced â€”
``None`` when the target has none â€” otherwise the OLD provider's endpoint/wire-protocol lingers
(#25106). A context pin is dropped only when its route identity changed (fail-closed).
Non-custom targets resolve credentials from env/auth.json/the pool, so an inline
``model.api_key`` is a leftover that would contaminate later custom resolution. For custom
targets the inline key belongs to ONE endpoint: it survives only a same-route re-pick (same
provider and base_url) â€” ``custom:a`` -> ``custom:b`` must not hand endpoint A's secret to B.
The ``key_env`` / ``api_key_env`` credential POINTER (written by custom-endpoint activation
and, for REGISTRY providers too, by the Desktop settings UI (#106336); resolved by
runtime_provider / auxiliary_client / ``auth._model_level_key_env``) clears only when the
route changed: left behind it routes the NEW provider's requests to the OLD endpoint's env
var, but a same-provider same-base_url model re-pick keeps it whatever the provider is. The
dashboard re-adds an explicitly submitted key / the target provider's own pointer after this
(``_apply_main_model_assignment`` / ``_resolve_assignment_credentials``).r>  r¡   r]   Nr  Úcontext_lengthr  r    rs   rW   rZ   r)  r¢   r*  )r2   r3   r  r  r]   r  r  r  rH   r6   r:   r;   Úselection_route_changedrg   )	rW  rX  r@  Úupdatesr  rG  Úroute_changedÚstaler¼   s	   &&       r$   Úmodel_selection_config_updatesr_  ò  sM  € ô$ &0Ð0AÄ4×%HÒ%HÑ!Èb€Ià�6×#Ñ# Z°×1GÑ1GØ�F—O‘O×+Ð+ t¨Z¸¿¹×9PÐ9PÈDð€Gð ˜9Ô$ÝFÙ#Ø—‘˜iÓ(×BÐB¨I¯M©M¸'Ó,BÀF×DTÑDTØ—‘˜jÓ)¨6¯?©?¸I¿M¹MÈ*Ó<UÐW]×WmÑWm÷oò oð )-ˆGÐ$Ñ%Ü�×'Ñ'×-Ð-¨2Ó.×4Ñ4Ó6×<Ñ<Ó>€FÜ+¨IÓ>€MØ'-×'8Ñ'8¸×'BÒ'BÇmˆY˜ÑÐZ\€EßØ�)˜]Ð+Õ+ˆÛˆØÖØˆG‹Lñ ð €Nr&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r@  r3   rW  r  r    rK   r"   )r#   s   "r$   r%   r%     s'   € ÷ lñ l tð lÐ5Fð lÈ4ñ lr&   c                ób  € ^ RI Hp \        V P                  R4      ;'       g    R4      P	                  4       P                  4       \        VP                  ;'       g    R4      P	                  4       P                  4       8w  d   R# V! V P                  R4      4      V! VP                  4      8g  # )z²Provider or endpoint differs between a ``model:`` block and the switch target. The one
route-identity test for endpoint-bound credentials (inline keys, ``key_env``, launch keys).)Únormalize_route_base_urlr¡   rs   Tr]   )r  rb  r6   rH   r:   r;   r  r]   )r@  rW  rb  s   && r$   r[  r[    s‡   € õ CÜ
ˆ9�=‰=˜Ó$×*Ð*¨Ó+×1Ñ1Ó3×9Ñ9Ó;¼sÀ6×CYÑCY×C_ÐC_Ð]_Ó?`×?fÑ?fÓ?h×?nÑ?nÓ?pÔpÙÙ# I§M¡M°*Ó$=Ó>ÑBZÐ[a×[jÑ[jÓBkÑkÐkr&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r@  r   rW  r  r    r3   r"   )r#   s   "r$   r%   r%   #  s'   € ÷ bñ b Sð bÐ2Cð bÈñ br&   c                ó,   € \        V \        W4      4      # )z›Apply the canonical shape to an in-memory ``model:`` dict (``None`` = key removed) for
callers that save a whole config document they are already mutating.)Ú_merge_selection_updatesr_  )r@  rW  s   &&r$   Úapply_model_selectionrf  #  s   € ô $ IÔ/MÈfÓ/`ÓaÐar&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   r@  r   r\  r;  r    r3   r"   )r#   s   "r$   r%   r%   )  s!   € ÷ ñ ¨ð °nð Èñ r&   c                ó¶   € \        V \        4      '       d   \        V 4      M/ p VP                  4        F!  w  r#Vf   V P                  VR 4       K  W0V&   K#  	  V # r1   )r2   r3   r´   Úpop)r@  r\  r¼   r   s   &&  r$   re  re  )  sM   € Ü#-¨i¼×#>Ò#>”�Y”ÀB€IØ—m‘m–o‰
ˆØŠ=Ø�M‰M˜#˜tÖ$à"�c‹Nñ	 &ð
 Ðr&   c               ó$   € V ^8„  d   QhRRRRRR/# )r   rW  r  Úconfig_pathr   r    rÌ   r"   )r#   s   "r$   r%   r%   3  s#   € ÷ %ñ %Ð$5ð %ÀCð %ÐSWñ %r&   c                ó:  € ^ RI Hp ^ RIHpHpHpHp V'       d	   V! V4      MV! 4       pV! V4      P                  R4      p\        W4      p	T;_uu_ 4        V! V4      p
V
P                  R4      pW¸8w  d   \        W4      p	\        W¹4      p\        V\        4      '       d#   VP                  4        VP                  V4       MWÊR&   V! Wz4       RRR4        \        P                  ! VR4       R#   + '       g   i     L*; i  \         \"        3 d     R# i ; i)u„  Write a successful :func:`switch_model` result to ``config_path`` (default:
``HERMES_HOME/config.yaml`` â€” the context override or ``HERMES_HOME`` at call time).

Build the complete selection from one raw snapshot, preserving sibling settings and secret
references, then publish once. Per-key publication can leave a mixed route after a failed
write or an overlapping selection. ``should_clear_context_pin`` can do cold-start disk I/O
â€” async callers run this on a worker thread.

The replace deletes keys missing from the snapshot, so every route decision (and its disk
I/O) is made from a pre-read BEFORE the snapshot; read -> merge -> replace is then a pure
in-memory section. Only when another writer changed ``model:`` in between are the updates
recomputed against the fresh block. ``_CONFIG_LOCK`` is in-process only: a cross-process
config lock, once one exists, must wrap the same section.)ÚPath)Ú_CONFIG_LOCKÚatomic_config_replacerÄ   Úread_user_config_rawr    Ni€  )Úpathlibrm  r³   rn  ro  rÄ   rp  rH   r_  re  r2   r3   rÎ   rÏ   r†  ÚchmodrÇ   ÚNotImplementedError)rW  rk  rm  rn  ro  rÄ   rp  rÈ   Úplanned_fromr\  Úconfigr@  r·   s   &&           r$   Úpersist_model_selectionrv  3  sã   € õ ßlÓlß +‰4�Ô±Ó1B€DÙ'¨Ó-×1Ñ1°'Ó:€LÜ,¨VÓB€Gß	ŠÙ% dÓ+ˆØ—J‘J˜wÓ'ˆ	ØÔ$Ü4°VÓGˆGÜ)¨)Ó=ˆÜ�i¤×&Ò&ð �O‰OÔØ×Ñ˜VÕ$à$�7‰OÙ˜dÔ+÷ 
ðÜ
�Š��uÖ÷! 
�ûô" Ô(Ð)ô Úðús   ÁA:C2ÃD Ã2D	ÄDÄDc               ó    € V ^8„  d   QhRRRR/# )r   rJ   r   r    râ  r"   )r#   s   "r$   r%   r%   [  s   € ÷ ?ñ ? cð ?¨nñ ?r&   c                ól   € \        V \        4      '       g   / # ^ RIHp V! V P	                  R4      4      # )rR  )Únormalize_extra_headersr³  )r2   r3   r³   ry  rH   )rJ   ry  s   & r$   rö  rö  [  s+   € Ü�eœT×"Ò"Øˆ	Ý9Ù" 5§9¡9¨_Ó#=Ó>Ð>r&   c               ó    € V ^8„  d   QhRRRR/# )r   rG   r6   r    r"   )r#   s   "r$   r%   r%   b  s   € ÷ ñ ˜#ð  #ñ r&   c                ó
  € V '       g   R#  ^ RI HpHpHp V! 4       f   V! 4       '       d"   V! V R4      ;'       g    RP	                  4       # ^ RIHp V! V 4      ;'       g    RP	                  4       #   \         d     R# i ; i)uÏ  Read a provider key env var the way the chat path does, honouring the per-profile scope.

With a secret scope installed (multiplexed gateway turn, dashboard/kanban workers) the scope's
verdict is authoritative: a hit is this profile's key, a miss must not borrow another profile's
value from the process env or the default ``.env``. Multiplexing on with no scope fails closed
(``UnscopedSecretError`` -> ""). Otherwise resolve through ``get_env_prefer_dotenv`` â€” the
chain ``client_lifecycle`` uses for the actual request â€” so a ``key_env`` that lives only in
``$HERMES_HOME/.env`` authenticates the ``/model`` verification probe (#109315) and a rotated
``.env`` beats a stale value inherited from the parent shell.rs   )Úcurrent_secret_scopeÚ
get_secretÚis_multiplex_active)Úget_env_prefer_dotenv)r  r|  r}  r~  r:   Úagent.credential_poolr  r¶   )rG   r|  r}  r~  r  s   &    r$   rÚ   rÚ   b  sv   € ÷ Ùðß\Ñ\ÙÓ!Ò-Ñ1D×1FÒ1FÙ˜t RÓ(×.Ð.¨B×5Ñ5Ó7Ð7Ý?Ù% dÓ+×1Ð1¨r×8Ñ8Ó:Ð:øÜô Úðús'   ŒA3 ¬A3 ¼A3 ÁA3 Á"A3 Á3BÂB)F)z*ri.language-model-service..language-model.r1   >   râ  ú::1ú0.0.0.0rã  )Frs   )NNrs   )NN)rs   NN)r"   NN)rs   rs   NNNNNN)Úcopilotzgithub-copilot)zopencode-zenzopencode-goÚopencode)rû  znous-portalÚnousresearchr…  )rs   rs   Frs   NN)•Ú__conditional_annotations__r~   Ú
__future__r   Úloggingr†  r.  Ú
contextlibr   Údataclassesr   r   Útypingr   r   r   r  r	   r
   r   r   r   r   r   r   r   Úhermes_cli.model_normalizer   Úagent.models_devr   r   r   r   r   Úutilsr   r   r   r   Ú!hermes_cli.model_switch_providersr   Ú	getLoggerrz   rÁ  rC   r4   rO   rS   ra   rt   ÚcompileÚ
IGNORECASErm   rb   r   rj   rp   ru   rw   r�   rŸ   r¤   r`   r¨   r¾   rÀ   rÁ   rÉ   rÒ   rÜ   rß   Ú	frozensetrå   rê   rì   r  r  r$  r1  r3  r;  rA  r`  ra  rb  rS  rF  rf  rj  rq  rŽ  r…  r¶   r   r¹  r½  rØ  rÊ  rË  rò  rý  r  r  r"  r  r  r@  rG  r  rE  rO  rU  r_  rn  ru  ry  r•  rœ  r:  r¾  rÄ  rÏ  rÊ  rÚ  rë  rð  rü  r  r÷  r  r  r!  r-  r2  r6  r:  r3   r0  r<  rA  rQ  rU  r_  r[  rf  re  rv  rö  rÚ   )r†  s   @r$   Ú<module>r”     s¾  øðô`õ #ã Û 	Û 	Ý ß (ß ,Ñ ,÷V÷ Võ Võ D÷`õ `ç [Ó [å Jð 
×	Ò	˜8Ó	$€õõ.\õ	Y÷õ"\ð-ð ð !ŸjšjÐ)RÐTV×TaÑTaÓbÐ ð +ZÐ ˜Ó YõõOõ
Sô�Jô ð+7Ø‘˜{¨OÓ<ð+7à
‘˜{¨MÓ:ð+7ð ‘˜{¨NÓ;ð+7ð ‘˜{¨HÓ5ð	+7ð
 ‘˜x¨Ó1ð+7ð 
‘˜x¨Ó/ð+7ð ‘˜x¨Ó1ð+7ð 	‘˜x¨Ó.ð+7ð 	‘˜x¨Ó.ð+7ð ‘˜x¨Ó2ð+7ð ‘˜z¨?Ó;ð+7ð ‘˜v vÓ.ð+7ð ‘˜|¨WÓ5ð+7ð ‘˜v vÓ.ð+7ð ‘˜y¨)Ó4ð+7ð  ‘˜x¨Ó4ð!+7ð" ‘˜|¨VÓ4ð#+7ð$ 
‘˜v uÓ-Ø
‘˜y¨&Ó1Ø
‘˜x¨Ó0Ø‘˜z¨9Ó5ñ++7€Ð'ó 7ô8�*ô ð$ 35Ð Ð/Ó 4õ$ð
 *,€Ð&Ó +÷1ðp +/Ð ˜Ó .ð (,Ð �nÓ +õ-õ"(õ(:õoñ  ÒHÓI€õ<ô˜
ô ðScØ02ðScØLNðScà%)ðScð (,ðScð MQ÷Scðp ÷)ð )ó ð)ñ6 �$Ô÷ð ó ðð ˜;¨°\À;ÐP_ÐaiÐktÐu€ØÐ1°=ÐBTÐU€õ[÷:!ð !ðR %7Ð !Ø(>Ð %Ø!0Ð ð
 &Ð'WØ)Ð+XØ"Ð$uðwÐ ñ �$Ô÷Gð Gó ðGõ8wõ8@÷ð õ :õ4"ôJ	\˜)ô 	\õ	5÷Kð K÷E/ð E/õPcõ+÷
ð 
÷	=ð 	=÷%ð %õP^õ$õNaõ*
põ	nõõ$nõ
gõ	õPõõ1õ4aõõ$-õ`ð ÷.Uð .Uó ð.Uõb*õZõ*Võ,õõ8=õ@õ;õ|)OõX	Qõõ*	õõ@3õl:õ

4õ ð0NØ
‡m‚mÑ1Ð3DÓEð0Nà
‡m‚mÑ?ÐASÓTð0Nð ‡m‚mÑ;¸^ÓLð0NÐ ˜nó N÷Kð Kõ*i÷Z$ð $õ.%õPlõbõ÷%õP?÷r&   