§
    ¦¨îi�µ ã            !      óê  — U d Z ddlmZ ddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ ddlmZmZmZ ddlmZ de› �Zd	Ze› d
�ZdZg d¢Zg d¢Zg d¢Zded<   daded<   g d¢Zded<   daded<   �d„d„Zi dg d¢“dg d¢“d e¦   «         “ddg“dg d ¢“d!g d"¢“d#g d$¢“d%g d&¢“d'd(d)g“d*g d+¢“d,g d-¢“d.g d/¢“d0d1d2g“d3g d/¢“d4g d5¢“d6g d5¢“d7g d8¢“g d9¢g d:¢g d;¢g d<¢g d=¢g d>¢g d?¢g d@¢g dA¢g dBœ
¥Z dCedD<   dE„ eD ¦   «         e dF<   �d…dL„Z!�d†�d‡dQ„Z"�dˆdS„Z#�d‰dW„Z$dXZ%dYedZ<   da&d[ed\<   �dŠd]„Z'd^Z(d_Z)dYed`<   i Z*daedb<   	 	 �d‹dddeœ�dŒdi„Z+�d�dj„Z,�dŽdn„Z-ddddMdddoœ�d�dr„Z. G ds„ dte¦  «        Z/ e/ddudv¦  «         e/dwdxdy¦  «         e/dFdzd{¦  «         e/d7d|d}¦  «         e/dd~d~¦  «         e/dd€d�¦  «         e/d*d‚dƒ¦  «         e/d„d…d†¦  «         e/dd‡dˆ¦  «         e/dd‰dŠ¦  «         e/d‹dŒd�¦  «         e/d!dŽd�¦  «         e/d#d�d‘¦  «         e/d’d“d”¦  «         e/d'd•d–¦  «         e/d%d—d˜¦  «         e/d,d™dš¦  «         e/d.d›dœ¦  «         e/d0d�dž¦  «         e/d4dŸd ¦  «         e/d6d¡d¢¦  «         e/d£d¤d¥¦  «         e/d¦d§d¨¦  «         e/d©dªd«¦  «         e/d¬d­d®¦  «         e/d¯d°d±¦  «         e/d²d³d´¦  «         e/dµd¶d·¦  «         e/d¸d¹dº¦  «        gZ0d»ed¼<   d½„ e0D ¦   «         Z1d¾e1d¿<   i dÀd%“dÁd%“dÂd%“dÃd%“dÄd“dÅd“dÆd“dÇd“dÈd“dÉd“dÊd!“dËd!“dÌd!“dÍd,“d3d,“dÎd.“dÏd.“i dÐd0“dÑd0“dÒd©“dÓd©“dÔd6“dÕd6“dÖd7“d×d7“dØd’“dÙd¯“dÚd¯“dÛd²“dÜd²“dÝdF“dÞdF“dßdF“dàd¬“¥i dád¬“dâd¬“dãd£“däd£“dåd£“dæd£“dçd„“dèd#“déd#“dêd‹“dëd‹“dìd‹“díd“dîd“dïdµ“dðdµ“dñdµ“¥dµd'd'd'd*d*d*d*d¿d¦dòœ
¥Z2�d�dô„Z3�d‘dõ„Z4�d’d÷„Z5	 �d“dddeœ�d”dù„Z6dddeœ�d•dú„Z7�d„dû„Z8�d‘dü„Z9	 �d“dddeœ�d”dý„Z:dddeœ�d•dþ„Z;i Z<dÿe�d <   �d–�d„Z=	 	 �d—�d˜�d„Z>	 	 	 �d™dddeœ�dš�d„Z?	 �d“dddeœ�d›�d„Z@�d��d„ZA�dœ�d„ZBdddeœ�d��d„ZC eDe1 E                    ¦   «         ¦  «         eDe2 E                    ¦   «         ¦  «        z  dwd¿hz  ZF�de�d<   �dž�d„ZG�dŸ�d„ZH�d��d„ZIdddeœ�d �d„ZJ�d¡�d„ZK�d¢�d„ZL eMh �d £¦  «        ZN�d£�d#„ZO�d¤�d%„ZP�d¤�d&„ZQ�d¥�d'„ZR�d¦�d(„ZS�d¦�d)„ZT eMh �d*£¦  «        ZU�d+e�d,<    eM�d-�d.h¦  «        ZV�d+e�d/<   �d§�d0„ZW�d¨�d1„ZX�d¨�d2„ZY�d©�d4„ZZ�d��d5„Z[ eMh �d6£¦  «        Z\�d+e�d7<   �dª�d9„Z]dddeœ�d«�d:„Z^�d¬�d­�d<„Z_�d®�d?„Z`�d¯�dA„Za�d°�dB„Zb	 �d±�d²�dD„Zci ad�dEe�dF<   �dGaedge�dH<   �dIZf�d³�d´�dK„Zg�dµ�dL„Zh�d±�d¶�dM„Zii �dN�dO“�dP�dO“�dQ�dO“�dR�dO“�dS�dT“�dU�dT“�dV�dT“�dW�dX“�dY�dZ“�d[�d\“�d]�dO“�d^�d\“�d_�d`“�da�dO“�db�dO“�dc�d.“�dd�de“�df�dg�dh�d.�de�df�dg�dh�d.�de�df�dg�dh�diœ¥Zj	 	 �d·�d¸�dk„Zkdd�dlœ�d¹�dm„Zl�dº�dn„Zm�d»�do„Zndd�dlœ�d¹�dp„Zo�d¼�dr„Zp�d¼�ds„Zqdd�dlœ�d½�dt„Zr	 	 �d¾�d¿�dv„Zs�d¬�d­�dw„Zt	 	 �d¾�dÀ�dx„Zu�dIZv�dÁ�dz„Zwdd�d{œ�dÂ�d~„Zx�dÃ�d€„Zy	 	 �d·dddeœ�dÄ�d�„Zzddd�d‚œ�dÅ�dƒ„Z{dS (Æ  uÃ   
Canonical model catalogs and lightweight validation helpers.

Add, remove, or reorder entries here â€” both `hermes setup` and
`hermes` provider-selection will pick up the change automatically.
é    )ÚannotationsN)Úget_close_matches)ÚPath)ÚAnyÚ
NamedTupleÚOptional)Ú__version__zhermes-cli/zhttps://api.githubcopilot.comú/modelszvscode/1.104.1)ÚminimalÚlowÚmediumÚhigh)r   r   r   )!©úmoonshotai/kimi-k2.6Úrecommended©úanthropic/claude-opus-4.7Ú ©úanthropic/claude-opus-4.6r   ©úanthropic/claude-sonnet-4.6r   )zqwen/qwen3.6-plusr   )úanthropic/claude-sonnet-4.5r   ©úanthropic/claude-haiku-4.5r   )zopenrouter/elephant-alphaÚfree)úopenai/gpt-5.5r   ©úopenai/gpt-5.4-minir   )úxiaomi/mimo-v2.5-pror   )úxiaomi/mimo-v2.5r   ©úopenai/gpt-5.3-codexr   )z!google/gemini-3-pro-image-previewr   )úgoogle/gemini-3-flash-previewr   ©úgoogle/gemini-3.1-pro-previewr   ©ú$google/gemini-3.1-flash-lite-previewr   )úqwen/qwen3.5-plus-02-15r   )úqwen/qwen3.5-35b-a3br   )ústepfun/step-3.5-flashr   ©úminimax/minimax-m2.7r   )úminimax/minimax-m2.5r   )úminimax/minimax-m2.5:freer   )úz-ai/glm-5.1r   )úz-ai/glm-5v-turbor   )úz-ai/glm-5-turbor   )zx-ai/grok-4.20r   )ú!nvidia/nemotron-3-super-120b-a12br   )z&nvidia/nemotron-3-super-120b-a12b:freer   )z#arcee-ai/trinity-large-preview:freer   )úarcee-ai/trinity-large-thinkingr   )úopenai/gpt-5.5-pror   )úopenai/gpt-5.4-nanor   úlist[tuple[str, str]]ÚOPENROUTER_MODELSzlist[tuple[str, str]] | NoneÚ_openrouter_catalog_cache)r   )zalibaba/qwen3.6-plusr   )zzai/glm-5.1r   r,   r   r   r   r   )úopenai/gpt-5.4r   r   r"   r%   )zgoogle/gemini-3-flashr   r'   )zxai/grok-4.20-reasoningr   ÚVERCEL_AI_GATEWAY_MODELSÚ_ai_gateway_catalog_cacheÚreturnú	list[str]c                 óB   — ddl m} m}  |t          | ¦  «        ¦  «        S )a  Derive the openai-codex curated list from codex_models.py.

    Single source of truth: DEFAULT_CODEX_MODELS + forward-compat synthesis.
    This keeps the gateway /model picker in sync with the CLI `hermes model`
    flow without maintaining a separate static list.
    r   ©ÚDEFAULT_CODEX_MODELSÚ_add_forward_compat_models)Úhermes_cli.codex_modelsrA   rB   Úlistr@   s     ú3/home/div/.hermes/hermes-agent/hermes_cli/models.pyÚ_codex_curated_modelsrF   b   s7   € ð YÐXÐXÐXÐXÐXÐXÐXØ%Ð%¥dÐ+?Ñ&@Ô&@ÑAÔAÐAó    Únous)r   r    r!   r   r   r   r   r   r   r   r#   úgoogle/gemini-3-pro-previewr$   r&   r(   r)   r*   r+   r-   r.   r/   r0   r1   r2   zx-ai/grok-4.20-betar3   r4   r5   r6   Úopenai)úgpt-5.4úgpt-5.4-miniú
gpt-5-miniúgpt-5.3-codexúgpt-5.2-codexúgpt-4.1úgpt-4oúgpt-4o-miniúopenai-codexúcopilot-acpÚcopilot)rK   rL   rM   rN   rO   rP   rQ   rR   úclaude-sonnet-4.6úclaude-sonnet-4úclaude-sonnet-4.5úclaude-haiku-4.5úgemini-3.1-pro-previewúgemini-3-pro-previewúgemini-3-flash-previewzgemini-2.5-prozgrok-code-fast-1Úgemini)rZ   r[   r\   zgemini-3.1-flash-lite-previewzgoogle-gemini-cli)rZ   r[   r\   Úzai)úglm-5.1úglm-5zglm-5v-turbozglm-5-turboúglm-4.7zglm-4.5zglm-4.5-flashÚxaizgrok-4.20-reasoningzgrok-4-1-fast-reasoningÚnvidia)	r3   znvidia/nemotron-3-nano-30b-a3bz(nvidia/llama-3.3-nemotron-super-49b-v1.5zqwen/qwen3.5-397b-a17bzdeepseek-ai/deepseek-v3.2r   zminimaxai/minimax-m2.5z	z-ai/glm5zopenai/gpt-oss-120bzkimi-coding)ú	kimi-k2.6ú	kimi-k2.5zkimi-for-codingúkimi-k2-thinkingzkimi-k2-thinking-turboúkimi-k2-turbo-previewúkimi-k2-0905-previewzkimi-coding-cn)rd   re   rf   rg   rh   Ústepfunzstep-3.5-flashzstep-3.5-flash-2603ÚmoonshotÚminimax)zMiniMax-M2.7úMiniMax-M2.5zMiniMax-M2.1z
MiniMax-M2ú
minimax-cnÚ	anthropic)zclaude-opus-4-7úclaude-opus-4-6úclaude-sonnet-4-6zclaude-opus-4-5-20251101zclaude-sonnet-4-5-20250929zclaude-opus-4-20250514zclaude-sonnet-4-20250514zclaude-haiku-4-5-20251001)zdeepseek-v4-prozdeepseek-v4-flashzdeepseek-chatzdeepseek-reasoner)úmimo-v2.5-proú	mimo-v2.5úmimo-v2-proúmimo-v2-omnizmimo-v2-flash)ztrinity-large-thinkingztrinity-large-previewztrinity-mini)#re   zgpt-5.4-prorK   rN   úgpt-5.2rO   úgpt-5.1zgpt-5.1-codexzgpt-5.1-codex-maxzgpt-5.1-codex-miniúgpt-5zgpt-5-codexz
gpt-5-nanoro   zclaude-opus-4-5zclaude-opus-4-1rp   úclaude-sonnet-4-5rW   úclaude-haiku-4-5zclaude-3-5-haikuzgemini-3.1-prozgemini-3-prozgemini-3-flashúminimax-m2.7úminimax-m2.5zminimax-m2.5-freezminimax-m2.1r`   ra   zglm-4.6rf   zkimi-k2zqwen3-coderz
big-pickle)rd   re   r_   r`   rq   rr   rs   rt   rz   r{   zqwen3.6-plusúqwen3.5-plus)r   r   r:   rI   r$   )re   r|   zqwen3-coder-pluszqwen3-coder-nextr`   ra   rl   )	zmoonshotai/Kimi-K2.5zQwen/Qwen3.5-397B-A17BzQwen/Qwen3.5-35B-A3Bzdeepseek-ai/DeepSeek-V3.2zMiniMaxAI/MiniMax-M2.5zzai-org/GLM-5zXiaomiMiMo/MiMo-V2-Flashzmoonshotai/Kimi-K2-Thinkingzmoonshotai/Kimi-K2.6)
zus.anthropic.claude-sonnet-4-6zus.anthropic.claude-opus-4-6-v1z+us.anthropic.claude-haiku-4-5-20251001-v1:0z,us.anthropic.claude-sonnet-4-5-20250929-v1:0zus.amazon.nova-pro-v1:0zus.amazon.nova-lite-v1:0zus.amazon.nova-micro-v1:0zdeepseek.v3.2z)us.meta.llama4-maverick-17b-instruct-v1:0z&us.meta.llama4-scout-17b-instruct-v1:0)
ÚdeepseekÚxiaomiÚarceeúopencode-zenúopencode-goÚkilocodeÚalibabaÚhuggingfaceÚbedrockúazure-foundryzdict[str, list[str]]Ú_PROVIDER_MODELSc                ó   — g | ]\  }}|‘ŒS © r‰   ©Ú.0ÚmidÚ_s      rE   ú
<listcomp>rŽ   ‡  s   € Ð!MÐ!MÐ!M©&¨#¨q #Ð!MÐ!MÐ!MrG   ú
ai-gatewayÚmodel_idÚstrÚpricingúdict[str, dict[str, str]]Úboolc                ó  — |                      | ¦  «        }|sdS 	 t          |                      dd¦  «        ¦  «        dk    o&t          |                      dd¦  «        ¦  «        dk    S # t          t          f$ r Y dS w xY w)zFReturn True if *model_id* has zero-cost prompt AND completion pricing.FÚpromptÚ1r   Ú
completion)ÚgetÚfloatÚ	TypeErrorÚ
ValueError)r�   r’   Úps      rE   Ú_is_model_freerž   ‘  sŽ   € à�Š�HÑÔ€AØð ØˆuðÝ�Q—U’U˜8 SÑ)Ô)Ñ*Ô*¨aÒ/ÐXµE¸!¿%º%ÀÈcÑ:RÔ:RÑ4SÔ4SÐWXÒ4XÐXøÝ•zÐ"ð ð ð Øˆuˆuðøøøs   ›AA) Á)A>Á=A>r   Úaccess_tokenÚportal_base_urlúdict[str, Any]c                ó˜  — |pd                      d¦  «        }|› d�}d| › �ddœ}	 t          j                             ||¬¦  «        }t          j                             |d¬	¦  «        5 }t          j        |                     ¦   «                              ¦   «         ¦  «        cd
d
d
¦  «         S # 1 swxY w Y   d
S # t          $ r i cY S w xY w)aï  Fetch the user's Nous Portal account/subscription info.

    Calls ``<portal>/api/oauth/account`` with the OAuth access token.

    Returns the parsed JSON dict on success, e.g.::

        {
            "subscription": {
                "plan": "Plus",
                "tier": 2,
                "monthly_charge": 20,
                "credits_remaining": 1686.60,
                ...
            },
            ...
        }

    Returns an empty dict on any failure (network, auth, parse).
    úhttps://portal.nousresearch.comú/z/api/oauth/accountúBearer úapplication/json)ÚAuthorizationÚAccept©Úheadersé   ©ÚtimeoutN)
ÚrstripÚurllibÚrequestÚRequestÚurlopenÚjsonÚloadsÚreadÚdecodeÚ	Exception)rŸ   r    ÚbaseÚurlrª   ÚreqÚresps          rE   Úfetch_nous_account_tierr¼      s%  € ð( Ð@Ð@×HÒHÈÑMÔM€DØÐ
%Ð
%Ð
%€Cà1 <Ð1Ð1Ø$ðð €GðÝŒn×$Ò$ S°'Ð$Ñ:Ô:ˆÝŒ^×#Ò# C°Ð#Ñ3Ô3ð 	4°tÝ”:˜dŸiši™kœk×0Ò0Ñ2Ô2Ñ3Ô3ð	4ð 	4ð 	4ð 	4ñ 	4ô 	4ð 	4ð 	4ð 	4ð 	4ð 	4ð 	4øøøð 	4ð 	4ð 	4ð 	4ð 	4ð 	4øåð ð ð Øˆ	ˆ	ˆ	ðøøøs6   ¦AB: Á(8B-Â B: Â-B1Â1B: Â4B1Â5B: Â:C	ÃC	Úaccount_infoc                óä   — |                       d¦  «        }t          |t          ¦  «        sdS |                      d¦  «        }|€dS 	 t          |¦  «        dk    S # t          t
          f$ r Y dS w xY w)uØ   Return True if the account info indicates a free (unpaid) tier.

    Checks ``subscription.monthly_charge == 0``.  Returns False when
    the field is missing or unparseable (assumes paid â€” don't block users).
    ÚsubscriptionFÚmonthly_chargeNr   )r™   Ú
isinstanceÚdictrš   r›   rœ   )r½   ÚsubÚcharges      rE   Úis_nous_free_tierrÅ   Â  s‡   € ð ×
Ò
˜>Ñ
*Ô
*€CÝ�c�4Ñ Ô ð ØˆuØ�WŠWÐ%Ñ&Ô&€FØ€~ØˆuðÝ�V‰}Œ} Ò!Ð!øÝ•zÐ"ð ð ð Øˆuˆuðøøøs   ÁA ÁA/Á.A/Ú	model_idsÚ	free_tierútuple[list[str], list[str]]c                óª   — |s| g fS |s| g fS g }g }| D ]=}t          ||¦  «        r|                     |¦  «         Œ(|                     |¦  «         Œ>||fS )a  Split Nous models into (selectable, unavailable) based on user tier.

    For paid-tier users: all models are selectable, none unavailable.

    For free-tier users: only free models are selectable; paid models
    are returned as unavailable (shown grayed out in the menu).
    )rž   Úappend)rÆ   r’   rÇ   Ú
selectableÚunavailablerŒ   s         rE   Úpartition_nous_models_by_tierrÍ   Ô  sŒ   € ð ð Ø˜2ˆÐàð Ø˜2ˆÐà€JØ€KØð $ð $ˆÝ˜#˜wÑ'Ô'ð 	$Ø×Ò˜cÑ"Ô"Ð"Ð"à×Ò˜sÑ#Ô#Ð#Ð#Ø˜Ð$Ð$rG   é´   ÚintÚ_FREE_TIER_CACHE_TTLztuple[bool, float] | NoneÚ_free_tier_cachec                 ó–  — t          j        ¦   «         } t          �t          \  }}| |z
  t          k     r|S 	 ddlm}m}  |d¬¦  «          |d¦  «        }|sd| fadS |                     dd	¦  «        }|                     d
d	¦  «        }|sd| fadS t          ||¦  «        }t          |¦  «        }	|	| fa|	S # t          $ r d| faY dS w xY w)u_  Check if the current Nous Portal user is on a free (unpaid) tier.

    Results are cached for ``_FREE_TIER_CACHE_TTL`` seconds to avoid
    hitting the Portal API on every call.  The cache is short-lived so
    that an account upgrade is reflected within a few minutes.

    Returns False (assume paid) on any error â€” never blocks paying users.
    Nr   )Úget_provider_auth_stateÚ resolve_nous_runtime_credentialsé<   )Úmin_key_ttl_secondsrH   FrŸ   r   r    )ÚtimeÚ	monotonicrÑ   rÐ   Úhermes_cli.authrÓ   rÔ   r™   r¼   rÅ   r·   )
ÚnowÚcached_resultÚ	cached_atrÓ   rÔ   ÚstaterŸ   Ú
portal_urlr½   Úresults
             rE   Úcheck_nous_free_tierrà   ø  s&  € õ Œ.Ñ
Ô
€CÝÐ#Ý#3Ñ ˆ�yØ�‰?Õ1Ò1Ð1Ø Ð ðØ]Ð]Ð]Ð]Ð]Ð]Ð]Ð]ð 	)Ð(¸RÐ@Ñ@Ô@Ð@à'Ð'¨Ñ/Ô/ˆØð 	Ø % s˜|ÐØ�5Ø—y’y °Ñ4Ô4ˆØ—Y’YÐ0°"Ñ5Ô5ˆ
Øð 	Ø % s˜|ÐØ�5å.¨|¸ZÑHÔHˆÝ" <Ñ0Ô0ˆØ" C˜=ÐØˆøÝð ð ð Ø! 3˜<ÐØˆuˆuðøøøs   ¶%B6 Á2B6 Â$B6 Â6CÃCz/api/nous/recommended-modelsiX  Ú_NOUS_RECOMMENDED_CACHE_TTLz'dict[str, tuple[dict[str, Any], float]]Ú_nous_recommended_cacheç      @F©Úforce_refreshr­   rš   rå   c               ól  — | pd                      d¦  «        }t          j        ¦   «         }t                               |¦  «        }|s|�|\  }}||z
  t
          k     r|S |› t          › �}	 t          j         	                    |ddi¬¦  «        }	t          j         
                    |	|¬¦  «        5 }
t          j        |
                     ¦   «                              ¦   «         ¦  «        }ddd¦  «         n# 1 swxY w Y   t          |t           ¦  «        si }n# t"          $ r i }Y nw xY w||ft          |<   |S )uü  Fetch the Nous Portal's curated recommended-models payload.

    Hits ``<portal>/api/nous/recommended-models``. The endpoint is public â€”
    no auth is required. Results are cached per portal URL for
    ``_NOUS_RECOMMENDED_CACHE_TTL`` seconds; pass ``force_refresh=True`` to
    bypass the cache.

    Returns the parsed JSON dict on success, or ``{}`` on any failure
    (network, parse, non-2xx). Callers must treat missing/null fields as
    "no recommendation" and fall back to their own default.
    r£   r¤   Nr¨   r¦   r©   r¬   )r®   r×   rØ   râ   r™   rá   ÚNOUS_RECOMMENDED_MODELS_PATHr¯   r°   r±   r²   r³   r´   rµ   r¶   rÁ   rÂ   r·   )r    r­   rå   r¸   rÚ   ÚcachedÚpayloadrÜ   r¹   rº   r»   Údatas               rE   Úfetch_nous_recommended_modelsrë   ;  s‹  € ð" Ð@Ð@×HÒHÈÑMÔM€DÝ
Œ.Ñ
Ô
€CÝ$×(Ò(¨Ñ.Ô.€FØð ˜VÐ/Ø#Ñˆ�Ø�‰?Õ8Ò8Ð8ØˆNàÐ
1Õ/Ð
1Ð
1€Cð
ÝŒn×$Ò$ØØÐ1Ð2ð %ñ 
ô 
ˆõ Œ^×#Ò# C°Ð#Ñ9Ô9ð 	4¸TÝ”:˜dŸiši™kœk×0Ò0Ñ2Ô2Ñ3Ô3ˆDð	4ð 	4ð 	4ñ 	4ô 	4ð 	4ð 	4ð 	4ð 	4ð 	4ð 	4øøøð 	4ð 	4ð 	4ð 	4å˜$¥Ñ%Ô%ð 	ØˆDøøÝð ð ð Øˆˆˆðøøøð &*¨3 KÕ˜DÑ!Ø€Ks7   Á*AD Â.9C3Ã'D Ã3C7Ã7D Ã:C7Ã;D ÄD%Ä$D%c                 ó.  — 	 ddl m} m}  |d¦  «        pi }t          |                     d¦  «        pd¦  «                             ¦   «         }|r|                     d¦  «        S t          | ¦  «                             d¦  «        S # t          $ r Y dS w xY w)zEBest-effort lookup of the Portal base URL the user is authed against.r   )ÚDEFAULT_NOUS_PORTAL_URLrÓ   rH   r    r   r¤   r£   )rÙ   rí   rÓ   r‘   r™   Ústripr®   r·   )rí   rÓ   rÝ   Úportals       rE   Ú_resolve_nous_portal_urlrð   e  sÌ   € ð1ð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð (Ð'¨Ñ/Ô/Ð5°2ˆÝ�U—Y’YÐ0Ñ1Ô1Ð7°RÑ8Ô8×>Ò>Ñ@Ô@ˆØð 	&Ø—=’= Ñ%Ô%Ð%ÝÐ*Ñ+Ô+×2Ò2°3Ñ7Ô7Ð7øÝð 1ð 1ð 1Ø0Ð0Ð0ð1øøøs   ‚A!B Á$!B Â
BÂBÚentryr   úOptional[str]c                óØ   — t          | t          ¦  «        sdS |                      d¦  «        }t          |t          ¦  «        r(|                     ¦   «         r|                     ¦   «         S dS )zGPull the ``modelName`` field from a recommended-model entry, else None.NÚ	modelName)rÁ   rÂ   r™   r‘   rî   )rñ   Ú
model_names     rE   Ú_extract_model_namerö   u  sf   € å�e�TÑ"Ô"ð ØˆtØ—’˜;Ñ'Ô'€JÝ�*�cÑ"Ô"ð " z×'7Ò'7Ñ'9Ô'9ð "Ø×ÒÑ!Ô!Ð!Øˆ4rG   )ÚvisionrÇ   r    rå   r÷   úOptional[bool]c                ó  — |pt          ¦   «         }t          ||¬¦  «        }|sdS |€"	 t          ¦   «         }n# t          $ r d}Y nw xY w| rd\  }}nd\  }}|r|gn||g}|D ]*}	t	          |                     |	¦  «        ¦  «        }
|
r|
c S Œ+dS )u  Return the Portal's recommended model name for an auxiliary task.

    Picks the best field from the Portal's recommended-models payload:

    * ``vision=True``  â†’ ``paidRecommendedVisionModel``  (paid tier) or
                         ``freeRecommendedVisionModel``  (free tier)
    * ``vision=False`` â†’ ``paidRecommendedCompactionModel`` or
                         ``freeRecommendedCompactionModel``

    When ``free_tier`` is ``None`` (default) the user's tier is auto-detected
    via :func:`check_nous_free_tier`. Pass an explicit bool to bypass the
    detection â€” useful for tests or when the caller already knows the tier.

    For paid-tier users we prefer the paid recommendation but gracefully fall
    back to the free recommendation if the Portal returned ``null`` for the
    paid field (common during the staged rollout of new paid models).

    Returns ``None`` when every candidate is missing, null, or the fetch
    fails â€” callers should fall back to their own default (currently
    ``google/gemini-3-flash-preview``).
    rä   NF)ÚpaidRecommendedVisionModelÚfreeRecommendedVisionModel)ÚpaidRecommendedCompactionModelÚfreeRecommendedCompactionModel)rð   rë   rà   r·   rö   r™   )r÷   rÇ   r    rå   r¸   ré   Úpaid_keyÚfree_keyÚ
candidatesÚkeyÚnames              rE   Úget_nous_recommended_aux_modelr    sí   € ð8 Ð8Õ6Ñ8Ô8€DÝ+¨DÀÐNÑNÔN€GØð ØˆtàÐð	Ý,Ñ.Ô.ˆIˆIøÝð 	ð 	ð 	ð ˆIˆIˆIð	øøøð
 ð `ØWÑˆ�(�(à_Ñˆ�(ð
  )ÐB�(��¨x¸Ð.B€JØð ð ˆÝ" 7§;¢;¨sÑ#3Ô#3Ñ4Ô4ˆØð 	ØˆKˆKˆKð	àˆ4s   ©8 ¸AÁAc                  ó.   — e Zd ZU ded<   ded<   ded<   dS )ÚProviderEntryr‘   ÚslugÚlabelÚtui_descN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r‰   rG   rE   r  r  Ã  s+   € € € € € € Ø€I€I�IØ€J€J�JØ€M€M�M€M€MrG   r  zNous Portalz(Nous Portal (Nous Research subscription)Ú
openrouterÚ
OpenRouterz%OpenRouter (100+ models, pay-per-use)zVercel AI Gatewayz:Vercel AI Gateway (200+ models, $5 free credit, no markup)Ú	Anthropicu4   Anthropic (Claude models â€” API key or Claude Code)zOpenAI Codexr~   zXiaomi MiMou:   Xiaomi MiMo (MiMo-V2.5 and V2 models â€” pro, omni, flash)z
NVIDIA NIMu>   NVIDIA NIM (Nemotron models â€” build.nvidia.com or local NIM)z
qwen-oauthzQwen OAuth (Portal)z(Qwen OAuth (reuses local Qwen CLI login)zGitHub Copilotz3GitHub Copilot (uses GITHUB_TOKEN or gh auth token)zGitHub Copilot ACPz3GitHub Copilot ACP (spawns `copilot --acp --stdio`)r„   zHugging Facez2Hugging Face Inference Providers (20+ open models)zGoogle AI Studiou6   Google AI Studio (Gemini models â€” native Gemini API)zGoogle Gemini (OAuth)zNGoogle Gemini via OAuth + Code Assist (free tier supported; no API key needed)r}   ÚDeepSeeku0   DeepSeek (DeepSeek-V3, R1, coder â€” direct API)ÚxAIu    xAI (Grok models â€” direct API)z
Z.AI / GLMz Z.AI / GLM (Zhipu AI direct API)zKimi / Kimi Coding Planz.Kimi Coding Plan (api.kimi.com) & Moonshot APIzKimi / Moonshot (China)z.Kimi / Moonshot China (Moonshot CN direct API)zStepFun Step Planz9StepFun Step Plan (agent/coding models via Step Plan API)ÚMiniMaxzMiniMax (global direct API)zMiniMax (China)z#MiniMax China (domestic direct API)rƒ   zAlibaba Cloud (DashScope)z8Alibaba Cloud / DashScope Coding (Qwen + multi-provider)úollama-cloudzOllama Cloudu6   Ollama Cloud (cloud-hosted open models â€” ollama.com)r   zArcee AIu(   Arcee AI (Trinity models â€” direct API)r‚   z	Kilo CodezKilo Code (Kilo Gateway API)r€   zOpenCode Zenz0OpenCode Zen (35+ curated models, pay-as-you-go)r�   zOpenCode Goz1OpenCode Go (open models, $10/month subscription)r…   zAWS Bedrocku>   AWS Bedrock (Claude, Nova, Llama, DeepSeek â€” IAM or API key)r†   zAzure FoundryuU   Azure Foundry (OpenAI-style or Anthropic-style endpoint â€” your Azure AI deployment)zlist[ProviderEntry]ÚCANONICAL_PROVIDERSc                ó(   — i | ]}|j         |j        “ŒS r‰   )r  r  ©r‹   r�   s     rE   ú
<dictcomp>r  ê  s   € ÐAÐAÐA¨�A”F˜AœGÐAÐAÐArG   zCustom endpointÚcustomÚglmzz-aizz.aiÚzhipuÚgithubzgithub-copilotzgithub-modelszgithub-modelzgithub-copilot-acpzcopilot-acp-agentÚgooglezgoogle-geminizgoogle-ai-studioÚkimizkimi-cnzmoonshot-cnÚstepzstepfun-coding-planzarcee-aiÚarceeaizminimax-chinaÚ
minimax_cnÚclaudezclaude-codez	deep-seekÚopencodeÚzenÚgozopencode-go-subÚ	aigatewayÚvercelzvercel-ai-gatewayÚkiloz	kilo-codezkilo-gatewayÚ	dashscopeÚaliyunÚqwenzalibaba-cloudzqwen-portalz
gemini-clizgemini-oauthÚhfzhugging-facezhuggingface-hubÚmimozxiaomi-mimoÚawszaws-bedrockzamazon-bedrock)
ÚamazonÚgrokzx-aizx.aiÚnimz
nvidia-nimzbuild-nvidiaÚnemotronÚollamaÚollama_cloudÚproviderc                óP   — t                                | g ¦  «        }|r|d         ndS )a�  Return the default model for a provider, or empty string if unknown.

    Uses the first entry in _PROVIDER_MODELS as the default.  This is the
    model a user would be offered first in the ``hermes model`` picker.

    Used as a fallback when the user has configured a provider but never
    selected a model (e.g. ``hermes auth add openai-codex`` without
    ``hermes model``).
    r   r   )r‡   r™   )r4  Úmodelss     rE   Úget_default_model_for_providerr7  /  s,   € õ ×!Ò! (¨BÑ/Ô/€FØÐ&ˆ6�!Œ9ˆ9 BÐ&rG   c                óþ   — t          | t          ¦  «        sdS 	 t          |                      dd¦  «        ¦  «        dk    o&t          |                      dd¦  «        ¦  «        dk    S # t          t
          f$ r Y dS w xY w)z=Return True when both prompt and completion pricing are zero.Fr–   Ú0r   r˜   ©rÁ   rÂ   rš   r™   r›   rœ   ©r’   s    rE   Ú_openrouter_model_is_freer<  =  sˆ   € å�g�tÑ$Ô$ð ØˆuðÝ�W—[’[ ¨3Ñ/Ô/Ñ0Ô0°AÒ5Ðd½%ÀÇÂÈLÐZ]Ñ@^Ô@^Ñ:_Ô:_ÐcdÒ:dÐdøÝ•zÐ"ð ð ð Øˆuˆuðøøøó   ™AA' Á'A<Á;A<Úitemc                ó�   — t          | t          ¦  «        sdS |                      d¦  «        }t          |t          ¦  «        sdS d|v S )u1  Return True when the model's ``supported_parameters`` advertise tool calling.

    hermes-agent is tool-calling-first â€” every provider path assumes the model
    can invoke tools. Models that don't advertise ``tools`` in their
    ``supported_parameters`` (e.g. image-only or completion-only models) cannot
    be driven by the agent loop and would fail at the first tool call.

    **Permissive when the field is missing.** Some OpenRouter-compatible gateways
    (Nous Portal, private mirrors, older catalog snapshots) don't populate
    ``supported_parameters`` at all. Treat that as "unknown capability â†’ allow"
    so the picker doesn't silently empty for those users. Only hide models
    whose ``supported_parameters`` is an explicit list that omits ``tools``.

    Ported from Kilo-Org/kilocode#9068.
    TÚsupported_parametersÚtools)rÁ   rÂ   r™   rD   )r>  Úparamss     rE   Ú _openrouter_model_supports_toolsrC  G  sO   € õ  �d�DÑ!Ô!ð ØˆtØ�XŠXÐ,Ñ-Ô-€FÝ�f�dÑ#Ô#ð àˆtØ�fÐÐrG   ç       @c               óä  — t           �|st          t           ¦  «        S 	 ddlm}  |¦   «         }n# t          $ r d}Y nw xY w|rt          |¦  «        nt          t
          ¦  «        }d„ |D ¦   «         }	 t          j                             dddi¬¦  «        }t          j         	                    || ¬	¦  «        5 }t          j        |                     ¦   «                              ¦   «         ¦  «        }ddd¦  «         n# 1 swxY w Y   n&# t          $ r t          t           p|¦  «        cY S w xY w|                     d
g ¦  «        }	t          |	t          ¦  «        st          t           p|¦  «        S i }
|	D ]V}t          |t           ¦  «        sŒt#          |                     d¦  «        pd¦  «                             ¦   «         }|sŒQ||
|<   ŒWg }|D ]g}|
                     |¦  «        }|€Œt'          |¦  «        sŒ*t)          |                     d¦  «        ¦  «        rdnd}|                     ||f¦  «         Œh|st          t           p|¦  «        S |d         \  }}|df|d<   |a t          |¦  «        S )zYReturn the curated OpenRouter picker list, refreshed from the live catalog when possible.Nr   )Úget_curated_openrouter_modelsc                ó   — g | ]\  }}|‘ŒS r‰   r‰   rŠ   s      rE   rŽ   z+fetch_openrouter_models.<locals>.<listcomp>u  ó   € Ð0Ð0Ð0™V˜S !�SÐ0Ð0Ð0rG   z#https://openrouter.ai/api/v1/modelsr¨   r¦   r©   r¬   rê   Úidr   r’   r   r   )r9   rD   Úhermes_cli.model_catalogrF  r·   r8   r¯   r°   r±   r²   r³   r´   rµ   r¶   r™   rÁ   rÂ   r‘   rî   rC  r<  rÊ   )r­   rå   rF  ÚremoteÚfallbackÚpreferred_idsrº   r»   ré   Ú
live_itemsÚ
live_by_idr>  rŒ   ÚcuratedÚpreferred_idÚ	live_itemÚdescÚfirst_idr�   s                      rE   Úfetch_openrouter_modelsrU  `  sù  € õ !Ð,°]Ð,ÝÕ-Ñ.Ô.Ð.ðØJÐJÐJÐJÐJÐJØ.Ð.Ñ0Ô0ˆˆøÝð ð ð Øˆˆˆðøøøà%ÐB�t�F‰|Œ|ˆ|­4Õ0AÑ+BÔ+B€HØ0Ð0 xÐ0Ñ0Ô0€Mð;ÝŒn×$Ò$Ø1ØÐ1Ð2ð %ñ 
ô 
ˆõ Œ^×#Ò# C°Ð#Ñ9Ô9ð 	7¸TÝ”j §¢¡¤×!3Ò!3Ñ!5Ô!5Ñ6Ô6ˆGð	7ð 	7ð 	7ñ 	7ô 	7ð 	7ð 	7ð 	7ð 	7ð 	7ð 	7øøøð 	7ð 	7ð 	7ð 	7øøåð ;ð ;ð ;ÝÕ-Ð9°Ñ:Ô:Ð:Ð:Ð:ð;øøøð —’˜V RÑ(Ô(€JÝ�j¥$Ñ'Ô'ð ;ÝÕ-Ð9°Ñ:Ô:Ð:à,.€JØð ð ˆÝ˜$¥Ñ%Ô%ð 	ØÝ�$—(’(˜4‘.”.Ð& BÑ'Ô'×-Ò-Ñ/Ô/ˆØð 	ØØˆ
�3‰ˆà%'€GØ%ð 
-ð 
-ˆØ—N’N <Ñ0Ô0ˆ	ØÐØõ 0°	Ñ:Ô:ð 	ØÝ2°9·=²=ÀÑ3KÔ3KÑLÔLÐTˆvˆvÐRTˆØ�Š˜ dÐ+Ñ,Ô,Ð,Ð,àð ;ÝÕ-Ð9°Ñ:Ô:Ð:à˜!”*�K€HˆaØ˜MÐ*€GˆA�JØ 'ÐÝ�‰=Œ=ÐsC   Ÿ0 °?¾?Á4AD	 Â89C=Ã1D	 Ã=DÄD	 ÄDÄD	 Ä	 D,Ä+D,c                ó6   — d„ t          | ¬¦  «        D ¦   «         S )z,Return just the OpenRouter model-id strings.c                ó   — g | ]\  }}|‘ŒS r‰   r‰   rŠ   s      rE   rŽ   zmodel_ids.<locals>.<listcomp>¦  ó   € ÐSÐSÐS‘F�C˜ˆCÐSÐSÐSrG   rä   )rU  rä   s    rE   rÆ   rÆ   ¤  ó"   € àSÐSÕ5ÀMÐRÑRÔRÐSÑSÔSÐSrG   c                 ó¼   — 	 ddl m}   | ¦   «         }n# t          $ r d}Y nw xY w|rt          |¦  «        S t          t                               dg ¦  «        ¦  «        S )a6  Return the curated Nous Portal model-id list.

    Prefers the remotely-hosted catalog manifest (published under
    ``website/static/api/model-catalog.json``); falls back to the in-repo
    snapshot in ``_PROVIDER_MODELS["nous"]`` when the manifest is
    unreachable. Always returns a list (never None).
    r   )Úget_curated_nous_modelsNrH   )rJ  r[  r·   rD   r‡   r™   )r[  rK  s     rE   Úget_curated_nous_model_idsr\  ©  s€   € ðØDÐDÐDÐDÐDÐDØ(Ð(Ñ*Ô*ˆˆøÝð ð ð Øˆˆˆðøøøàð Ý�F‰|Œ|ÐÝÕ ×$Ò$ V¨RÑ0Ô0Ñ1Ô1Ð1s   ‚ “"¡"c                óþ   — t          | t          ¦  «        sdS 	 t          |                      dd¦  «        ¦  «        dk    o&t          |                      dd¦  «        ¦  «        dk    S # t          t
          f$ r Y dS w xY w)zCReturn True if an AI Gateway model has $0 input AND output pricing.FÚinputr9  r   Úoutputr:  r;  s    rE   Ú_ai_gateway_model_is_freer`  »  sˆ   € å�g�tÑ$Ô$ð ØˆuðÝ�W—[’[ ¨#Ñ.Ô.Ñ/Ô/°1Ò4Ð_½¸w¿{º{È8ÐUXÑ?YÔ?YÑ9ZÔ9ZÐ^_Ò9_Ð_øÝ•zÐ"ð ð ð Øˆuˆuðøøør=  c               ó>  ‡— t           �|st          t           ¦  «        S ddlm} t          t          ¦  «        }d„ |D ¦   «         }	 t
          j                             |                     d¦  «        › d�ddi¬	¦  «        }t
          j         	                    || ¬
¦  «        5 }t          j        |                     ¦   «                              ¦   «         ¦  «        }ddd¦  «         n# 1 swxY w Y   n&# t          $ r t          t           p|¦  «        cY S w xY w|                     dg ¦  «        }t!          |t          ¦  «        st          t           p|¦  «        S i }	|D ]V}
t!          |
t"          ¦  «        sŒt%          |
                     d¦  «        pd¦  «                             ¦   «         }|sŒQ|
|	|<   ŒWg }|D ]W}|	                     |¦  «        }|€Œt)          |                     d¦  «        ¦  «        rdnd}|                     ||f¦  «         ŒX|st          t           p|¦  «        S t-          d„ |	                     ¦   «         D ¦   «         d¦  «        Š‰r'ˆfd„|D ¦   «         }|                     d‰df¦  «         n|d         \  }}|df|d<   |a t          |¦  «        S )zYReturn the curated AI Gateway picker list, refreshed from the live catalog when possible.Nr   ©ÚAI_GATEWAY_BASE_URLc                ó   — g | ]\  }}|‘ŒS r‰   r‰   rŠ   s      rE   rŽ   z+fetch_ai_gateway_models.<locals>.<listcomp>Ó  rH  rG   r¤   r
   r¨   r¦   r©   r¬   rê   rI  r   r’   r   c              3  óŽ   K  — | ]@\  }}|                      d ¦  «        ¯t          |                     d¦  «        ¦  «        ¯<|V — ŒAdS )zmoonshotai/r’   N)Ú
startswithr`  r™   )r‹   rŒ   r>  s      rE   ú	<genexpr>z*fetch_ai_gateway_models.<locals>.<genexpr>ú  sj   è è € ð 	
ð 	
á��TØ�~Š~˜mÑ,Ô,ð	
õ *¨$¯(ª(°9Ñ*=Ô*=Ñ>Ô>ð		
Øð	
ð 	
ð 	
ð 	
ð 	
ð 	
rG   c                ó*   •— g | ]\  }}|‰k    ¯||f‘ŒS r‰   r‰   )r‹   rŒ   rS  Úfree_moonshots      €rE   rŽ   z+fetch_ai_gateway_models.<locals>.<listcomp>  s+   ø€ ÐPÐPÐP¡9 3¨¸3À-Ò;OÐ;O�C˜�;Ð;OÐ;OÐ;OrG   r   )r<   rD   Úhermes_constantsrc  r;   r¯   r°   r±   r®   r²   r³   r´   rµ   r¶   r·   r™   rÁ   rÂ   r‘   rî   r`  rÊ   ÚnextÚitemsÚinsert)r­   rå   rc  rL  rM  rº   r»   ré   rN  rO  r>  rŒ   rP  rQ  rR  rS  rT  r�   ri  s                     @rE   Úfetch_ai_gateway_modelsrn  Å  s1  ø€ õ !Ð,°]Ð,ÝÕ-Ñ.Ô.Ð.à4Ð4Ð4Ð4Ð4Ð4åÕ,Ñ-Ô-€HØ0Ð0 xÐ0Ñ0Ô0€Mð;ÝŒn×$Ò$Ø"×)Ò)¨#Ñ.Ô.Ð7Ð7Ð7ØÐ1Ð2ð %ñ 
ô 
ˆõ Œ^×#Ò# C°Ð#Ñ9Ô9ð 	7¸TÝ”j §¢¡¤×!3Ò!3Ñ!5Ô!5Ñ6Ô6ˆGð	7ð 	7ð 	7ñ 	7ô 	7ð 	7ð 	7ð 	7ð 	7ð 	7ð 	7øøøð 	7ð 	7ð 	7ð 	7øøåð ;ð ;ð ;ÝÕ-Ð9°Ñ:Ô:Ð:Ð:Ð:ð;øøøð —’˜V RÑ(Ô(€JÝ�j¥$Ñ'Ô'ð ;ÝÕ-Ð9°Ñ:Ô:Ð:à,.€JØð ð ˆÝ˜$¥Ñ%Ô%ð 	ØÝ�$—(’(˜4‘.”.Ð& BÑ'Ô'×-Ò-Ñ/Ô/ˆØð 	ØØˆ
�3‰ˆà%'€GØ%ð -ð -ˆØ—N’N <Ñ0Ô0ˆ	ØÐØÝ2°9·=²=ÀÑ3KÔ3KÑLÔLÐTˆvˆvÐRTˆØ�Š˜ dÐ+Ñ,Ô,Ð,Ð,àð ;ÝÕ-Ð9°Ñ:Ô:Ð:õ ð	
ð 	
à'×-Ò-Ñ/Ô/ð	
ñ 	
ô 	
ð 	ñô €Mð ð /ØPÐPÐPÐP°ÐPÑPÔPˆØ�Š�q˜=¨-Ð8Ñ9Ô9Ð9Ð9à˜a”j‰ˆ�!Ø Ð.ˆ�‰
à 'ÐÝ�‰=Œ=Ðs7   ÁAC1 Â 9C%ÃC1 Ã%C)Ã)C1 Ã,C)Ã-C1 Ã1 DÄDc                ó6   — d„ t          | ¬¦  «        D ¦   «         S )z,Return just the AI Gateway model-id strings.c                ó   — g | ]\  }}|‘ŒS r‰   r‰   rŠ   s      rE   rŽ   z(ai_gateway_model_ids.<locals>.<listcomp>  rX  rG   rä   )rn  rä   s    rE   Úai_gateway_model_idsrq    rY  rG   z$dict[str, dict[str, dict[str, str]]]Ú_pricing_cacheÚper_token_strc                óz   — 	 t          | ¦  «        }n# t          t          f$ r Y dS w xY w|dk    rdS |dz  }d|d›�S )uÐ  Convert a per-token price string to a human-friendly $/Mtok string.

    Always uses 2 decimal places so that prices align vertically when
    right-justified in a column (the decimal point stays in the same position).

    Examples:
        "0.000003"   â†’ "$3.00"      (per million tokens)
        "0.00003"    â†’ "$30.00"
        "0.00000015" â†’ "$0.15"
        "0.0000001"  â†’ "$0.10"
        "0.00018"    â†’ "$180.00"
        "0"          â†’ "free"
    ú?r   r   i@B ú$z.2f)rš   r›   rœ   )rs  ÚvalÚper_ms      rE   Ú_format_price_per_mtokry    sb   € ðÝ�MÑ"Ô"ˆˆøÝ•zÐ"ð ð ð Øˆsˆsðøøøà
ˆa‚x€xØˆvØ�)‰O€EØˆuˆ?ˆ?ˆ?Ðs   ‚ ’'¦'ú      r6  Úpricing_mapÚcurrent_modelÚindentc                óþ  — | sg S g }d}| D ]¶\  }}||k    }|                      |¦  «        }	|	rtt          |	                      dd¦  «        ¦  «        }
t          |	                      dd¦  «        ¦  «        }|	                      dd¦  «        }|rt          |¦  «        nd}|rd}nd\  }
}}|                     ||
|||f¦  «         Œ·t          d„ |D ¦   «         ¦  «        d	z   }t          t          d
„ |D ¦   «         d¬¦  «        t          d„ |D ¦   «         d¬¦  «        d¦  «        }|r)t          t          d„ |D ¦   «         d¬¦  «        d¦  «        nd}g }|rb|                     |› dd|› �›ddd|› �›ddd|› �›ddd|› �›d�	¦  «         |                     |› d|z  › dd|z  › dd|z  › dd|z  › �¦  «         nT|                     |› dd|› �›ddd|› �›ddd|› �›d�¦  «         |                     |› d|z  › dd|z  › dd|z  › �¦  «         |D ]r\  }}
}}}|rdnd}|r5|                     |› |d|› �›d|
d|› �›d|d|› �›d|d|› �›|› �	¦  «         ŒE|                     |› |d|› �›d|
d|› �›d|d|› �›|› �¦  «         Œs|S )z´Build a column-aligned model+pricing table for terminal display.

    Returns a list of pre-formatted lines ready to print.
    *models* is ``[(model_id, description), ...]``.
    Fr–   r   r˜   Úinput_cache_readT)r   r   r   c              3  ó@   K  — | ]}t          |d          ¦  «        V — ŒdS )r   N©Úlen©r‹   Úrs     rE   rg  z-format_model_pricing_table.<locals>.<genexpr>S  s,   è è € Ð+Ð+ •3�q˜”t‘9”9Ð+Ð+Ð+Ð+Ð+Ð+rG   é   c              3  óP   K  — | ]!}|d          ¯
t          |d          ¦  «        V — Œ"dS )é   Nr�  rƒ  s     rE   rg  z-format_model_pricing_table.<locals>.<genexpr>V  ó5   è è € Ð-Ð-˜1¨¨!¬Ð-�S��1”‰YŒYÐ-Ð-Ð-Ð-Ð-Ð-rG   é   )Údefaultc              3  óP   K  — | ]!}|d          ¯
t          |d          ¦  «        V — Œ"dS )r…  Nr�  rƒ  s     rE   rg  z-format_model_pricing_table.<locals>.<genexpr>W  rˆ  rG   é   c              3  óP   K  — | ]!}|d          ¯
t          |d          ¦  «        V — Œ"dS )rŒ  Nr�  rƒ  s     rE   rg  z-format_model_pricing_table.<locals>.<genexpr>[  rˆ  rG   é   r   ÚModelú<ú ÚInú>z  ÚOutÚCachez  /Mtokú-u     â†� current)r™   ry  rÊ   Úmax)r6  r{  r|  r}  ÚrowsÚ	has_cacherŒ   Ú_descÚis_curr�   ÚinpÚoutÚ
cache_readÚcacheÚname_colÚ	price_colÚ	cache_colÚlinesÚmarkers                      rE   Úformat_model_pricing_tabler¥  4  sò  € ð ð Øˆ	ð 35€DØ€IØð 4ð 4‰
ˆˆUØ˜Ò%ˆØ�OŠO˜CÑ Ô ˆØð 	)Ý(¨¯ª¨x¸Ñ)<Ô)<Ñ=Ô=ˆCÝ(¨¯ª¨|¸RÑ)@Ô)@ÑAÔAˆCØŸšÐ1°2Ñ6Ô6ˆJØ:DÐLÕ*¨:Ñ6Ô6Ð6È"ˆEØð !Ø �	øà(‰OˆC��eØ�Š�S˜#˜s E¨6Ð2Ñ3Ô3Ð3Ð3åÐ+Ð+ dÐ+Ñ+Ô+Ñ+Ô+¨aÑ/€HåÝÐ-Ð- Ð-Ñ-Ô-°qÐ9Ñ9Ô9ÝÐ-Ð- Ð-Ñ-Ô-°qÐ9Ñ9Ô9Ø	ñô €Ið 
ð•ÝÐ-Ð- Ð-Ñ-Ô-°qÐ9Ñ9Ô9Ø	ñô ð ð ð ð €Eð ð WØ�Š˜Ð~ Ð~¨(Ð~Ð~Ð~Ð~°dÐ~¸YÐ~Ð~Ð~Ð~È5Ð~ÐS\Ð~Ð~Ð~Ð~ÐahÐ~ÐktÐ~Ð~Ð~Ð~Ð~ÑÔÐØ�Š˜Ðh  h¡ÐhÐh°°y±ÐhÐhÀCÈ)ÁOÐhÐhÐWZÐ]fÑWfÐhÐhÑiÔiÐiÐià�Š˜Ðf Ðf¨(ÐfÐfÐfÐf°dÐf¸YÐfÐfÐfÐfÈ5ÐfÐS\ÐfÐfÐfÐfÐfÑgÔgÐgØ�Š˜ÐU  h¡ÐUÐU°°y±ÐUÐUÀCÈ)ÁOÐUÐUÑVÔVÐVà(,ð fð fÑ$ˆˆS�#�u˜fØ$*Ð2��°ˆØð 	fØ�LŠL˜FÐz CÐz¨(ÐzÐzÐzÐz°cÐz¸IÐzÐzÐzÐzÈ#ÐzÐPYÐzÐzÐzÐzÐ^cÐzÐfoÐzÐzÐzÐrxÐzÐzÑ{Ô{Ð{Ð{à�LŠL˜FÐd CÐd¨(ÐdÐdÐdÐd°cÐd¸IÐdÐdÐdÐdÈ#ÐdÐPYÐdÐdÐdÐ\bÐdÐdÑeÔeÐeÐeà€LrG   úhttps://openrouter.ai/apiÚapi_keyú
str | NoneÚbase_urlc               ó4  — |pd                      d¦  «        }|s|t          v rt          |         S |                      d¦  «        dz   }dt          dœ}| rd| › �|d<   	 t          j                             ||¬¦  «        }t          j                             ||¬	¦  «        5 }t          j        | 	                    ¦   «          
                    ¦   «         ¦  «        }	d
d
d
¦  «         n# 1 swxY w Y   n# t          $ r i t          |<   i cY S w xY wi }
|	                     dg ¦  «        D ]é}|                     d¦  «        }|                     d¦  «        }|r»t          |t          ¦  «        r¦t          |                     dd¦  «        ¦  «        t          |                     dd¦  «        ¦  «        dœ}|                     d¦  «        rt          |d         ¦  «        |d<   |                     d¦  «        rt          |d         ¦  «        |d<   ||
|<   Œê|
t          |<   |
S )zâFetch ``/v1/models`` and return ``{model_id: {prompt, completion}}`` pricing.

    Results are cached per *base_url* so repeated calls are free.
    Works with any OpenRouter-compatible endpoint (OpenRouter, Nous Portal).
    r   r¤   z
/v1/modelsr¦   )r¨   ú
User-Agentr¥   r§   r©   r¬   Nrê   rI  r’   r–   r˜   ©r–   r˜   r  Úinput_cache_write)r®   rr  Ú_HERMES_USER_AGENTr¯   r°   r±   r²   r³   r´   rµ   r¶   r·   r™   rÁ   rÂ   r‘   )r§  r©  r­   rå   Ú	cache_keyr¹   rª   rº   r»   ré   rß   r>  rŒ   r’   rñ   s                  rE   Úfetch_models_with_pricingr°  r  sp  € ð �˜R×'Ò'¨Ñ,Ô,€IØð )˜Y­.Ð8Ð8Ý˜iÔ(Ð(à
×
Ò
˜3Ñ
Ô
 ,Ñ
.€Cà$Ý(ðð €Gð ð 7Ø#6¨WÐ#6Ð#6ˆ�Ñ ðÝŒn×$Ò$ S°'Ð$Ñ:Ô:ˆÝŒ^×#Ò# C°Ð#Ñ9Ô9ð 	7¸TÝ”j §¢¡¤×!3Ò!3Ñ!5Ô!5Ñ6Ô6ˆGð	7ð 	7ð 	7ñ 	7ô 	7ð 	7ð 	7ð 	7ð 	7ð 	7ð 	7øøøð 	7ð 	7ð 	7ð 	7øøåð ð ð Ø$&��yÑ!Øˆ	ˆ	ˆ	ðøøøð )+€FØ—’˜F BÑ'Ô'ð  ð  ˆØ�hŠh�t‰nŒnˆØ—(’(˜9Ñ%Ô%ˆØð 		 •:˜g¥tÑ,Ô,ð 		 å˜gŸkšk¨(°BÑ7Ô7Ñ8Ô8Ý! '§+¢+¨l¸BÑ"?Ô"?Ñ@Ô@ð%ð %ˆEð �{Š{Ð-Ñ.Ô.ð MÝ,/°Ð8JÔ0KÑ,LÔ,L�Ð(Ñ)Ø�{Š{Ð.Ñ/Ô/ð OÝ-0°Ð9LÔ1MÑ-NÔ-N�Ð)Ñ*ØˆF�3‰Køà &…N�9ÑØ€Ms7   ÁAC0 Â9C$ÃC0 Ã$C(Ã(C0 Ã+C(Ã,C0 Ã0D	ÄD	c               ó   — ddl m} |                     d¦  «        }|s|t          v rt          |         S 	 t          j                             |› d�ddi¬¦  «        }t          j                             || ¬¦  «        5 }t          j	        | 
                    ¦   «                              ¦   «         ¦  «        }d	d	d	¦  «         n# 1 swxY w Y   n# t          $ r i t          |<   i cY S w xY wi }|                     d
g ¦  «        D �]}t          |t          ¦  «        sŒ|                     d¦  «        }	|                     d¦  «        }
|	rt          |
t          ¦  «        sŒ[t!          |
                     dd¦  «        ¦  «        t!          |
                     dd¦  «        ¦  «        dœ}|
                     d¦  «        rt!          |
d         ¦  «        |d<   |
                     d¦  «        rt!          |
d         ¦  «        |d<   |||	<   �Œ|t          |<   |S )zøFetch Vercel AI Gateway /v1/models and return hermes-shaped pricing.

    Vercel uses ``input`` / ``output`` field names; hermes's picker expects
    ``prompt`` / ``completion``. This translates. Cache read/write field names
    already match.
    r   rb  r¤   r
   r¨   r¦   r©   r¬   Nrê   rI  r’   r^  r   r_  r¬  r  r­  )rj  rc  r®   rr  r¯   r°   r±   r²   r³   r´   rµ   r¶   r·   r™   rÁ   rÂ   r‘   )r­   rå   rc  r¯  rº   r»   ré   rß   r>  rŒ   r’   rñ   s               rE   Úfetch_ai_gateway_pricingr²  ¥  sj  € ð 5Ð4Ð4Ð4Ð4Ð4à#×*Ò*¨3Ñ/Ô/€IØð )˜Y­.Ð8Ð8Ý˜iÔ(Ð(ð	ÝŒn×$Ò$ØÐ!Ð!Ð!ØÐ1Ð2ð %ñ 
ô 
ˆõ Œ^×#Ò# C°Ð#Ñ9Ô9ð 	7¸TÝ”j §¢¡¤×!3Ò!3Ñ!5Ô!5Ñ6Ô6ˆGð	7ð 	7ð 	7ñ 	7ô 	7ð 	7ð 	7ð 	7ð 	7ð 	7ð 	7øøøð 	7ð 	7ð 	7ð 	7øøåð ð ð Ø$&��yÑ!Øˆ	ˆ	ˆ	ðøøøð )+€FØ—’˜F BÑ'Ô'ð ñ ˆÝ˜$¥Ñ%Ô%ð 	ØØ�hŠh�t‰nŒnˆØ—(’(˜9Ñ%Ô%ˆØð 	�
 7­DÑ1Ô1ð 	Øå˜'Ÿ+š+ g¨rÑ2Ô2Ñ3Ô3Ý˜gŸkšk¨(°BÑ7Ô7Ñ8Ô8ð!
ð !
ˆð �;Š;Ð)Ñ*Ô*ð 	IÝ(+¨GÐ4FÔ,GÑ(HÔ(HˆEÐ$Ñ%Ø�;Š;Ð*Ñ+Ô+ð 	KÝ),¨WÐ5HÔ-IÑ)JÔ)JˆEÐ%Ñ&Øˆˆs‰‰à &…N�9ÑØ€Ms6   µAC Á<9CÂ5C ÃCÃC ÃCÃ	C ÃC&Ã%C&c                 óP   — t          j        dd¦  «                             ¦   «         S )z1Best-effort OpenRouter API key for pricing fetch.ÚOPENROUTER_API_KEYr   )ÚosÚgetenvrî   r‰   rG   rE   Ú_resolve_openrouter_api_keyr·  ×  s!   € åŒ9Ð)¨2Ñ.Ô.×4Ò4Ñ6Ô6Ð6rG   útuple[str, str]c                 ó¦   — 	 ddl m}   | ¦   «         }|r,|                     dd¦  «        |                     dd¦  «        fS n# t          $ r Y nw xY wdS )zIReturn ``(api_key, base_url)`` for Nous Portal pricing, or empty strings.r   )rÔ   r§  r   r©  )r   r   )rÙ   rÔ   r™   r·   )rÔ   Úcredss     rE   Ú!_resolve_nous_pricing_credentialsr»  Ü  s‚   € ðØDÐDÐDÐDÐDÐDØ0Ð0Ñ2Ô2ˆØð 	IØ—I’I˜i¨Ñ,Ô,¨e¯iªi¸
ÀBÑ.GÔ.GÐHÐHð	Iøåð ð ð Øˆðøøøàˆ8s   ‚=A Á
AÁAc               óV  — t          | ¦  «        }|dk    rt          t          ¦   «         d|¬¦  «        S |dk    rt          |¬¦  «        S |dk    rYt	          ¦   «         \  }}|rF|                     d¦  «        }|                     d¦  «        r
|d	d
…         }t          |||¬¦  «        S i S )zQReturn live pricing for providers that support it (openrouter, nous, ai-gateway).r  r¦  )r§  r©  rå   r�   rä   rH   r¤   ú/v1Néýÿÿÿ)Únormalize_providerr°  r·  r²  r»  r®   Úendswith)r4  rå   Ú
normalizedr§  r©  Ústrippeds         rE   Úget_pricing_for_providerrÃ  è  sÞ   € å# HÑ-Ô-€JØ�\Ò!Ð!Ý(Ý/Ñ1Ô1Ø0Ø'ð
ñ 
ô 
ð 	
ð
 �\Ò!Ð!Ý'°mÐDÑDÔDÐDØ�VÒÐÝ=Ñ?Ô?Ñˆ�Øð 
	ð  —’ sÑ+Ô+ˆHØ× Ò  Ñ'Ô'ð )Ø# C R Cœ=�Ý,ØØ!Ø+ðñ ô ð ð
 €IrG   úset[str]Ú_KNOWN_PROVIDER_NAMESúlist[dict[str, str]]c                 óâ  — d„ t           D ¦   «         dgz   } i }t                               ¦   «         D ].\  }}|                     |g ¦  «                             |¦  «         Œ/g }| D �]	}t
                               ||¦  «        }|                     |g ¦  «        }d}	 ddlm}	m	}
 |dk    r2t          ¦   «         pd}t          |                     ¦   «         ¦  «        }ng|dk    r |
t          j        dd¦  «        ¦  «        }nB |	|¦  «        }t          |                     d	¦  «        p|                     d
¦  «        ¦  «        }n# t          $ r Y nw xY w|                     ||||dœ¦  «         �Œ|S )aR  Return info about all providers the user could use with ``provider:model``.

    Each dict has ``id``, ``label``, and ``aliases``.
    Checks which providers have valid credentials configured.

    Derives the provider list from :data:`CANONICAL_PROVIDERS` (single
    source of truth shared with ``hermes model``, ``/model``, etc.).
    c                ó   — g | ]	}|j         ‘Œ
S r‰   )r  r  s     rE   rŽ   z,list_available_providers.<locals>.<listcomp>  s   € Ð:Ð:Ð: �a”fÐ:Ð:Ð:rG   r  Fr   )Úget_auth_statusÚhas_usable_secretr   r  r´  Ú	logged_inÚ
configured)rI  r  ÚaliasesÚauthenticated)r  Ú_PROVIDER_ALIASESrl  Ú
setdefaultrÊ   Ú_PROVIDER_LABELSr™   rÙ   rÉ  rÊ  Ú_get_custom_base_urlr”   rî   rµ  r¶  r·   )Úprovider_orderÚaliases_forÚaliasÚ	canonicalrß   Úpidr  Ú
alias_listÚ	has_credsrÉ  rÊ  Úcustom_base_urlÚstatuss                rE   Úlist_available_providersrÜ    s»  € ð ;Ð:Õ&9Ð:Ñ:Ô:¸h¸ZÑG€Nð )+€KÝ-×3Ò3Ñ5Ô5ð <ð <ÑˆˆyØ×Ò˜y¨"Ñ-Ô-×4Ò4°UÑ;Ô;Ð;Ð;à€FØð ñ ˆÝ ×$Ò$ S¨#Ñ.Ô.ˆØ —_’_ S¨"Ñ-Ô-ˆ
àˆ	ð	ØJÐJÐJÐJÐJÐJÐJÐJØ�hŠˆÝ"6Ñ"8Ô"8Ð">¸B�Ý  ×!6Ò!6Ñ!8Ô!8Ñ9Ô9�	�	Ø˜Ò$Ð$Ø-Ð-­b¬iÐ8LÈbÑ.QÔ.QÑRÔR�	�	à(˜¨Ñ-Ô-�Ý  §¢¨KÑ!8Ô!8Ð!T¸F¿JºJÀ|Ñ<TÔ<TÑUÔU�	øøÝð 	ð 	ð 	ØˆDð	øøøà�ŠØØØ!Ø&ð	
ð 
ñ 	ô 	ð 	ñ 	ð €Ms   ÂB'EÅ
EÅEÚrawÚcurrent_providerc                ó  — |                       ¦   «         }|                     d¦  «        }|dk    rÐ|d|…                               ¦   «                              ¦   «         }||dz   d…                               ¦   «         }|r�|r|t          v rv|dk    r_d|v r[|                     d¦  «        }|d|…                               ¦   «         }||dz   d…                               ¦   «         }|r	|rd|› �|fS t	          |¦  «        |fS ||fS )uh  Parse ``/model`` input into ``(provider, model)``.

    Supports ``provider:model`` syntax to switch providers at runtime::

        openrouter:anthropic/claude-sonnet-4.5  â†’  ("openrouter", "anthropic/claude-sonnet-4.5")
        nous:hermes-3                           â†’  ("nous", "hermes-3")
        anthropic/claude-sonnet-4.5             â†’  (current_provider, "anthropic/claude-sonnet-4.5")
        gpt-5.4                                 â†’  (current_provider, "gpt-5.4")

    The colon is only treated as a provider delimiter if the left side is a
    recognized provider name or alias.  This avoids misinterpreting model names
    that happen to contain colons (e.g. ``anthropic/claude-3.5-sonnet:beta``).

    Returns ``(provider, model)`` where *provider* is either the explicit
    provider from the input or *current_provider* if none was specified.
    ú:r   Nr‡  r  zcustom:)rî   ÚfindÚlowerrÅ  r¿  )	rÝ  rÞ  rÂ  ÚcolonÚprovider_partÚ
model_partÚsecond_colonÚcustom_nameÚactual_models	            rE   Úparse_model_inputré  7  s0  € ð" �yŠy‰{Œ{€HØ�MŠM˜#ÑÔ€EØˆq‚y€yØ   % Ô(×.Ò.Ñ0Ô0×6Ò6Ñ8Ô8ˆØ˜e a™i˜j˜jÔ)×/Ò/Ñ1Ô1ˆ
Øð 
	C˜Zð 
	C¨MÕ=RÐ,RÐ,Rð  Ò(Ð(¨S°JÐ->Ð->Ø)Ÿš¨sÑ3Ô3�Ø(¨¨,¨Ô7×=Ò=Ñ?Ô?�Ø)¨,¸Ñ*:Ð*;Ð*;Ô<×BÒBÑDÔD�Øð C <ð CØ3 kÐ3Ð3°\ÐBÐBÝ& }Ñ5Ô5°zÐBÐBØ˜hÐ'Ð'rG   c                 ó
  — 	 ddl m}   | ¦   «         }|                     di ¦  «        }t          |t          ¦  «        r5t          |                     dd¦  «        ¦  «                             ¦   «         S n# t          $ r Y nw xY wdS )z2Get the custom endpoint base_url from config.yaml.r   )Úload_configÚmodelr©  r   )Úhermes_cli.configrë  r™   rÁ   rÂ   r‘   rî   r·   )rë  ÚconfigÚ	model_cfgs      rE   rÒ  rÒ  [  s›   € ðØ1Ð1Ð1Ð1Ð1Ð1Ø�‘”ˆØ—J’J˜w¨Ñ+Ô+ˆ	Ý�i¥Ñ&Ô&ð 	>Ý�y—}’} Z°Ñ4Ô4Ñ5Ô5×;Ò;Ñ=Ô=Ð=ð	>øåð ð ð Øˆðøøøàˆ2s   ‚A/A3 Á3
B Á?B c               óÔ   — t          | ¦  «        }|dk    rt          |¬¦  «        S t          |¦  «        }|rd„ |D ¦   «         S t                               |g ¦  «        }d„ |D ¦   «         S )zíReturn ``(model_id, description)`` tuples for a provider's model list.

    Tries to fetch the live model list from the provider's API first,
    falling back to the static ``_PROVIDER_MODELS`` catalog if the API
    is unreachable.
    r  rä   c                ó   — g | ]}|d f‘ŒS ©r   r‰   ©r‹   Úms     rE   rŽ   z/curated_models_for_provider.<locals>.<listcomp>z  s   € Ð&Ð&Ð&˜A��B�Ð&Ð&Ð&rG   c                ó   — g | ]}|d f‘ŒS rò  r‰   ró  s     rE   rŽ   z/curated_models_for_provider.<locals>.<listcomp>~  s   € Ð$Ð$Ð$˜ˆQ�ˆGÐ$Ð$Ð$rG   )r¿  rU  Úprovider_model_idsr‡   r™   )r4  rå   rÁ  Úliver6  s        rE   Úcurated_models_for_providerrø  h  sƒ   € õ $ HÑ-Ô-€JØ�\Ò!Ð!Ý&°]ÐCÑCÔCÐCõ ˜jÑ)Ô)€DØð 'Ø&Ð& Ð&Ñ&Ô&Ð&õ ×!Ò! *¨bÑ1Ô1€FØ$Ð$˜VÐ$Ñ$Ô$Ð$rG   c                óŒ   — | pd                      ¦   «                              ¦   «         }t          | ¦  «        }d„ ||fD ¦   «         S )Nr   c                ó   — h | ]}|¯|’ŒS r‰   r‰   )r‹   Úks     rE   ú	<setcomp>z!_provider_keys.<locals>.<setcomp>„  s   € Ð.Ð.Ð.�!¨AÐ.ˆAÐ.Ð.Ð.rG   )rî   râ  r¿  )r4  r  rÁ  s      rE   Ú_provider_keysrý  �  sI   € Øˆ>�r×
 Ò
 Ñ
"Ô
"×
(Ò
(Ñ
*Ô
*€CÝ# HÑ-Ô-€JØ.Ð.˜˜ZÐ(Ð.Ñ.Ô.Ð.rG   Ú
name_lowerÚ	providersc                ó:   ‡ — t          ˆ fd„|D ¦   «         ¦  «        S )Nc              3  ó„   •K  — | ]:}t                                |g ¦  «        D ]}‰|                     ¦   «         k    V — ŒŒ;d S ©N)r‡   r™   râ  )r‹   r4  rì  rþ  s      €rE   rg  z-_model_in_provider_catalog.<locals>.<genexpr>ˆ  sk   øè è € ð ð àÝ%×)Ò)¨(°BÑ7Ô7ðð ð ð 	�e—k’k‘m”mÒ#ðð ð ð ð ð ð rG   )Úany)rþ  rÿ  s   ` rE   Ú_model_in_provider_catalogr  ‡  s;   ø€ Ýð ð ð ð à!ðñ ô ñ ô ð rG   >   rH   rU   r‚   r  r�   Úcurrent_keysúOptional[tuple[str, str]]c                ó`  ‡‡— 	 ddl m} n# t          $ r Y dS w xY w|                     | ¦  «        }|€dS |j        Š|j        Šd	ˆˆfd„}|D ]} ||¦  «        x}r||fc S Œt          D ]#}||v s	|t          v rŒ ||¦  «        x}r||fc S Œ$t          D ]}||v r ||¦  «        x}r||fc S ŒdS )
zDResolve short aliases (e.g. sonnet/opus) using static catalogs only.r   )ÚMODEL_ALIASESNr4  r‘   r=   rò   c                óî   •— t                                | g ¦  «        }|sd S | t          v r‰› d‰› �n‰                     ¦   «         }|D ]-}|                     ¦   «                              |¦  «        r|c S Œ.d S )Nr¤   )r‡   r™   Ú_AGGREGATOR_PROVIDERSrâ  rf  )r4  r6  Úprefixrì  ÚfamilyÚvendors       €€rE   Ú_matchz+_resolve_static_model_alias.<locals>._match¥  sœ   ø€ Ý!×%Ò% h°Ñ3Ô3ˆØð 	Ø�4ð Õ0Ð0Ð0ð Ð Ð ˜Ð Ð Ð àß
Š%‰'Œ'ð	 	ð
 ð 	ð 	ˆEØ�{Š{‰}Œ}×'Ò'¨Ñ/Ô/ð Ø���ðàˆtrG   )r4  r‘   r=   rò   )Úhermes_cli.model_switchr  r·   r™   r  r  r‡   r
  )	rþ  r  r  Úidentityr  r4  Úmatchedr  r  s	          @@rE   Ú_resolve_static_model_aliasr  ”  sm  øø€ ð
Ø9Ð9Ð9Ð9Ð9Ð9Ð9øÝð ð ð Øˆtˆtðøøøð × Ò  Ñ,Ô,€HØÐØˆtàŒ_€FØŒ_€Fðð ð ð ð ð ð ð !ð %ð %ˆØ�f˜XÑ&Ô&Ð&ˆ7ð 	%Ø˜WÐ$Ð$Ð$Ð$ð	%õ %ð %ð %ˆØ�|Ð#Ð# xÕ3HÐ'HÐ'HØØ�f˜XÑ&Ô&Ð&ˆ7ð 	%Ø˜WÐ$Ð$Ð$Ð$ð	%õ *ð %ð %ˆØ�|Ð#Ð#°F°F¸8Ñ4DÔ4DÐ)D¨Ð#Ø˜WÐ$Ð$Ð$Ð$øàˆ4s   „ ‹
˜rõ   c                ó  ‡	— | pd                      ¦   «         }|sdS |                     ¦   «         Š	t          |¦  «        }t          ‰	|¦  «        }|r|S t                               ‰	‰	¦  «        }|dvr4t                               |g ¦  «        }|t          v r|r||vr
||d         fS t          ‰	|¦  «        rdS t           	                    ¦   «         D ]4\  }}||v s	|t          v rŒt          ˆ	fd„|D ¦   «         ¦  «        r||fc S Œ5dS )a  Auto-detect a provider from static catalogs only.

    Returns ``(provider_id, model_name)``. The model name may be remapped
    when a static alias or bare provider name resolves to a catalog default.
    Returns ``None`` when no confident match is found.
    r   N>   r  r  r   c              3  óH   •K  — | ]}‰|                      ¦   «         k    V — Œd S r  ©râ  )r‹   rô  rþ  s     €rE   rg  z3detect_static_provider_for_model.<locals>.<genexpr>ñ  s0   øè è € Ð7Ð7¨1ˆz˜QŸWšW™YœYÒ&Ð7Ð7Ð7Ð7Ð7Ð7rG   )rî   râ  rý  r  rÏ  r™   r‡   rÑ  r  rl  r
  r  )
rõ   rÞ  r  r  Úalias_matchÚresolved_providerÚdefault_modelsr×  r6  rþ  s
            @rE   Ú detect_static_provider_for_modelr  Ä  s]  ø€ ð Ð˜"×#Ò#Ñ%Ô%€DØð Øˆtà—’‘”€JÝ!Ð"2Ñ3Ô3€Lå-¨j¸,ÑGÔG€KØð ØÐõ *×-Ò-¨j¸*ÑEÔEÐØÐ 8Ð8Ð8Ý)×-Ò-Ð.?ÀÑDÔDˆàÕ!1Ð1Ð1Øð 2à!¨Ð5Ð5à% ~°aÔ'8Ð9Ð9õ " *¨lÑ;Ô;ð Øˆtõ (×-Ò-Ñ/Ô/ð ð ‰ˆˆVØ�,ÐÐ #Õ)>Ð">Ð">ØÝÐ7Ð7Ð7Ð7°Ð7Ñ7Ô7Ñ7Ô7ð 	Ø˜�;ÐÐÐð	ð ˆ4rG   c                ó  — | pd                      ¦   «         }|sdS t          ||¦  «        }|r|S t          |                     ¦   «         t	          |¦  «        ¦  «        rdS t          |¦  «        }|r|dk    rd|fS ||k    rd|fS dS dS )u«  Auto-detect the best provider for a model name.

    Returns ``(provider_id, model_name)`` â€” the model name may be remapped
    (e.g. bare ``deepseek-chat`` â†’ ``deepseek/deepseek-chat`` for OpenRouter).
    Returns ``None`` when no confident match is found.

    Priority:
    0. Bare provider name â†’ switch to that provider's default model
    1. Direct provider static catalog match
    2. OpenRouter catalog match
    r   Nr  )rî   r  r  râ  rý  Ú_find_openrouter_slug)rõ   rÞ  r  Ústatic_matchÚor_slugs        rE   Údetect_provider_for_modelr  ÷  s¸   € ð Ð˜"×#Ò#Ñ%Ô%€DØð Øˆtå3°DÐ:JÑKÔK€LØð ØÐÝ! $§*¢*¡,¤,µÐ?OÑ0PÔ0PÑQÔQð Øˆtõ $ DÑ)Ô)€GØð Ø˜|Ò+Ð+Ø  'Ð*Ð*à�dŠ?ˆ?Ø  'Ð*Ð*Øˆtàˆ4rG   c                óH  — |                       ¦   «                              ¦   «         }|sdS t          ¦   «         D ]}||                     ¦   «         k    r|c S Œt          ¦   «         D ];}d|v r5|                     dd¦  «        \  }}||                     ¦   «         k    r|c S Œ<dS )u  Find the full OpenRouter model slug for a bare or partial model name.

    Handles:
    - Exact match: ``anthropic/claude-opus-4.6`` â†’ as-is
    - Bare name: ``deepseek-chat`` â†’ ``deepseek/deepseek-chat``
    - Bare name: ``claude-opus-4.6`` â†’ ``anthropic/claude-opus-4.6``
    Nr¤   r‡  )rî   râ  rÆ   Úsplit)rõ   rþ  rŒ   r�   rå  s        rE   r  r    s¿   € ð ×!Ò!Ñ#Ô#×)Ò)Ñ+Ô+€JØð Øˆtõ ‰{Œ{ð ð ˆØ˜Ÿš™œÒ$Ð$ØˆJˆJˆJð %õ ‰{Œ{ð ð ˆØ�#ˆ:ˆ:ØŸIšI c¨1Ñ-Ô-‰MˆAˆzØ˜Z×-Ò-Ñ/Ô/Ò/Ð/Ø�
�
�
øàˆ4rG   c                óˆ   — | pd                      ¦   «                              ¦   «         }t                               ||¦  «        S )uó   Normalize provider aliases to Hermes' canonical provider ids.

    Note: ``"auto"`` passes through unchanged â€” use
    ``hermes_cli.auth.resolve_provider()`` to resolve it to a concrete
    provider based on credentials and environment.
    r  )rî   râ  rÏ  r™   )r4  rÁ  s     rE   r¿  r¿  9  s<   € ð Ð*˜l×1Ò1Ñ3Ô3×9Ò9Ñ;Ô;€JÝ× Ò  ¨ZÑ8Ô8Ð8rG   c                ó¾   — | pd                      ¦   «         }|                     ¦   «         }|dk    rdS t          |¦  «        }t                               ||pd¦  «        S )z9Return a human-friendly label for a provider id or alias.r  ÚautoÚAutor  )rî   râ  r¿  rÑ  r™   )r4  ÚoriginalrÁ  s      rE   Úprovider_labelr&  D  s_   € àÐ(˜L×/Ò/Ñ1Ô1€HØ—’Ñ!Ô!€JØ�VÒÐØˆvÝ# JÑ/Ô/€JÝ×Ò 
¨HÐ,D¸ÑEÔEÐErG   >   úo4-miniúgpt-4.1-miniúgpt-4.1-nanoÚo3rw   rQ   rP   rv   ru   rK   rM   rR   rL   zfrozenset[str]Ú_PRIORITY_PROCESSING_MODELSro   zclaude-opus-4.6Ú_ANTHROPIC_FAST_MODE_MODELSc                ó°   — t          | pd¦  «                             ¦   «                              ¦   «         }d|v r|                     dd¦  «        d         }|S )z]Strip vendor/ prefix from a model ID (e.g. 'anthropic/claude-opus-4-6' -> 'claude-opus-4-6').r   r¤   r‡  )r‘   rî   râ  r   )r�   rÝ  s     rE   Ú_strip_vendor_prefixr.  k  sQ   € å
ˆhˆn˜"Ñ
Ô
×
#Ò
#Ñ
%Ô
%×
+Ò
+Ñ
-Ô
-€CØ
ˆc€z€zØ�iŠi˜˜QÑÔ Ô"ˆØ€JrG   c                óœ   — t          t          | pd¦  «        ¦  «        }|t          v rdS |                     d¦  «        d         }|t          v S )zDReturn whether Hermes should expose the /fast toggle for this model.r   Trà  r   )r.  r‘   r+  r   r,  ©r�   rÝ  r¸   s      rE   Úmodel_supports_fast_moder1  s  sN   € å
�s 8 >¨rÑ2Ô2Ñ
3Ô
3€CØ
Õ)Ð)Ð)Øˆtð �9Š9�S‰>Œ>˜!Ô€DØÕ.Ð.Ð.rG   c                ó†   — t          t          | pd¦  «        ¦  «        }|                     d¦  «        d         }|t          v S )zGReturn True if the model supports Anthropic's fast mode (speed='fast').r   rà  r   )r.  r‘   r   r,  r0  s      rE   Ú_is_anthropic_fast_modelr3  ~  s;   € å
�s 8 >¨rÑ2Ô2Ñ
3Ô
3€CØ�9Š9�S‰>Œ>˜!Ô€DØÕ.Ð.Ð.rG   údict[str, Any] | Nonec                óR   — t          | ¦  «        sdS t          | ¦  «        rddiS ddiS )uâ  Return request_overrides for fast/priority mode, or None if unsupported.

    Returns provider-appropriate overrides:
    - OpenAI models: ``{"service_tier": "priority"}`` (Priority Processing)
    - Anthropic models: ``{"speed": "fast"}`` (Anthropic Fast Mode beta)

    The overrides are injected into the API request kwargs by
    ``_build_api_kwargs`` in run_agent.py â€” each API path handles its own
    keys (service_tier for OpenAI/Codex, speed for Anthropic Messages).
    NÚspeedÚfastÚservice_tierÚpriority)r1  r3  )r�   s    rE   Úresolve_fast_mode_overridesr:  …  s?   € õ $ HÑ-Ô-ð ØˆtÝ Ñ)Ô)ð !Ø˜Ð Ð Ø˜JÐ'Ð'rG   c                 ó´   — 	 ddl m}   | d¦  «        }t          |                     d¦  «        pd¦  «                             ¦   «         S # t
          $ r Y dS w xY w)z@Best-effort GitHub token for fetching the Copilot model catalog.r   ©Ú$resolve_api_key_provider_credentialsrU   r§  r   )rÙ   r=  r‘   r™   rî   r·   )r=  rº  s     rE   Ú _resolve_copilot_catalog_api_keyr>  —  sv   € ðØHÐHÐHÐHÐHÐHà4Ð4°YÑ?Ô?ˆÝ�5—9’9˜YÑ'Ô'Ð-¨2Ñ.Ô.×4Ò4Ñ6Ô6Ð6øÝð ð ð Øˆrˆrðøøøs   ‚AA	 Á	
AÁA>   r^   ÚgroqÚcoherer]   r  rc   Úmistralr}   r‚   Ú	fireworksÚ
perplexityÚ
togetherair„   r�   r€   Ú_MODELS_DEV_PREFERREDrP  c                óæ  — 	 ddl m}  || ¦  «        }n# t          $ r g }Y nw xY w|st          |¦  «        S t	          ¦   «         }g }|D ]R}t          |¦  «                             ¦   «         }||v rŒ(|                     |¦  «         |                     |¦  «         ŒS|D ]R}t          |¦  «                             ¦   «         }||v rŒ(|                     |¦  «         |                     |¦  «         ŒS|S )u²  Merge curated list with fresh models.dev entries for a preferred provider.

    Returns models.dev entries first (in models.dev order), then any
    curated-only entries appended. Preserves case for curated fallbacks
    (e.g. ``MiniMax-M2.7``) while trusting models.dev for newer variants.

    If models.dev is unreachable or returns nothing, the curated list is
    returned unchanged â€” this is the offline/CI fallback path.
    r   ©Úlist_agentic_models)	Úagent.models_devrH  r·   rD   Úsetr‘   râ  ÚaddrÊ   )r4  rP  rH  ÚmdevÚ
seen_lowerÚmergedrŒ   r  s           rE   Ú_merge_with_models_devrO  Ã  s,  € ðØ8Ð8Ð8Ð8Ð8Ð8Ø"Ð" 8Ñ,Ô,ˆˆøÝð ð ð Øˆˆˆðøøøð ð Ý�G‰}Œ}Ðõ ™5œ5€JØ€FØð ð ˆÝ�#‰hŒh�nŠnÑÔˆØ�*ÐÐØØ�Š�sÑÔÐØ�Š�cÑÔÐÐØð ð ˆÝ�#‰hŒh�nŠnÑÔˆØ�*ÐÐØØ�Š�sÑÔÐØ�Š�cÑÔÐÐØ€Ms   ‚ ”#¢#c               óò  — t          | ¦  «        }|dk    rt          |¬¦  «        S |dk    rOddlm} d}	 ddlm}  |d¬	¦  «        }|                     d
¦  «        }n# t          $ r d}Y nw xY w ||¬¦  «        S |dv r_	 t          t          ¦   «         ¦  «        }|r|S n# t          $ r Y nw xY w|dk    r(t          t                               dg ¦  «        ¦  «        S |dk    r_	 ddlm}m}	  |	¦   «         }|r9 ||                     d
d¦  «        |                     dd¦  «        ¬¦  «        }|r|S n# t          $ r Y nw xY w|dk    r§	 ddlm}
  |
d¦  «        }t          |                     d
¦  «        pd¦  «                             ¦   «         }t          |                     d¦  «        pd¦  «                             ¦   «         }|r|rt#          ||¦  «        }|r|S n# t          $ r Y nw xY w|dk    rt%          ¦   «         }|r|S |dk    rt'          ¦   «         }|r|S |dk    rt)          |¬¦  «        }|r|S |dk    r�t+          j        dd¦  «                             ¦   «         }|rdt+          j        dd¦  «                             ¦   «                              d¦  «        }|pd}	 t#          ||¦  «        }|r|S n# t          $ r Y nw xY w|dk    rct1          ¦   «         }|rSt+          j        dd¦  «        p)t+          j        dd¦  «        pt+          j        d d¦  «        }t#          ||¦  «        }|r|S t          t                               |g ¦  «        ¦  «        }|t2          v rt5          ||¦  «        S |S )!a¬  Return the best known model catalog for a provider.

    Tries live API endpoints for providers that support them (Codex, Nous),
    falling back to static lists. For providers in ``_MODELS_DEV_PREFERRED``
    (opencode-go/zen, xiaomi, deepseek, smaller inference providers, etc.),
    models.dev entries are merged on top of curated so new models released
    on the platform appear in ``/model`` without a Hermes release.
    r  rä   rS   r   )Úget_codex_model_idsN)Ú!resolve_codex_runtime_credentialsT)Úrefresh_if_expiringr§  )rŸ   >   rU   rT   rT   rU   rH   )Úfetch_nous_modelsrÔ   r   r©  )r§  Úinference_base_urlri   r<  rn   r�   r  rJ   ÚOPENAI_API_KEYÚOPENAI_BASE_URLr¤   zhttps://api.openai.com/v1r  ÚCUSTOM_API_KEYr´  )r¿  rÆ   rC   rQ  rÙ   rR  r™   r·   Ú_fetch_github_modelsr>  rD   r‡   rT  rÔ   r=  r‘   rî   Úfetch_api_modelsÚ_fetch_anthropic_modelsÚ_fetch_ai_gateway_modelsÚfetch_ollama_cloud_modelsrµ  r¶  r®   rÒ  rE  rO  )r4  rå   rÁ  rQ  rŸ   rR  rº  r÷  rT  rÔ   r=  r§  r©  Úbase_rawr¸   Úcurated_statics                   rE   rö  rö  è  s”  € õ $ HÑ-Ô-€JØ�\Ò!Ð!Ý }Ð5Ñ5Ô5Ð5Ø�^Ò#Ð#Ø?Ð?Ð?Ð?Ð?Ð?ð ˆð	 ØIÐIÐIÐIÐIÐIà5Ð5È$ÐOÑOÔOˆEØ Ÿ9š9 YÑ/Ô/ˆLˆLøÝð 	 ð 	 ð 	 ØˆLˆLˆLð	 øøøà"Ð"°Ð=Ñ=Ô=Ð=ØÐ/Ð/Ð/ð	Ý'Õ(HÑ(JÔ(JÑKÔKˆDØð Ø�ðøåð 	ð 	ð 	ØˆDð	øøøà˜Ò&Ð&ÝÕ(×,Ò,¨Y¸Ñ;Ô;Ñ<Ô<Ð<Ø�VÒÐð	Ø[Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ø4Ð4Ñ6Ô6ˆEØð  Ø(Ð(°·²¸9ÀbÑ1IÔ1IÐ^c×^gÒ^gÐhrÐtvÑ^wÔ^wÐxÑxÔx�Øð  Ø�KøøÝð 	ð 	ð 	ØˆDð	øøøà�YÒÐð	ØLÐLÐLÐLÐLÐLà8Ð8¸ÑCÔCˆEÝ˜%Ÿ)š) IÑ.Ô.Ð4°"Ñ5Ô5×;Ò;Ñ=Ô=ˆGÝ˜5Ÿ9š9 ZÑ0Ô0Ð6°BÑ7Ô7×=Ò=Ñ?Ô?ˆHØð  ˜8ð  Ý'¨°Ñ:Ô:�Øð  Ø�KøøÝð 	ð 	ð 	ØˆDð	øøøà�[Ò Ð Ý&Ñ(Ô(ˆØð 	ØˆKØ�\Ò!Ð!Ý'Ñ)Ô)ˆØð 	ØˆKØ�^Ò#Ð#Ý(°}ÐEÑEÔEˆØð 	ØˆKØ�XÒÐÝ”)Ð,¨bÑ1Ô1×7Ò7Ñ9Ô9ˆØð 	Ý”yÐ!2°BÑ7Ô7×=Ò=Ñ?Ô?×FÒFÀsÑKÔKˆHØÐ:Ð:ˆDðÝ'¨°Ñ6Ô6�Øð  Ø�Kð øåð ð ð Ø�ðøøøà�XÒÐÝ'Ñ)Ô)ˆØð 		õ ”	Ð*¨BÑ/Ô/ð 7Ý”9Ð-¨rÑ2Ô2ð7å”9Ð1°2Ñ6Ô6ð õ
 $ G¨XÑ6Ô6ˆDØð Ø�ÝÕ*×.Ò.¨z¸2Ñ>Ô>Ñ?Ô?€NØÕ*Ð*Ð*Ý% j°.ÑAÔAÐAØÐs[   µ'A ÁA,Á+A,Â B  Â 
B-Â,B-Ã%AD3 Ä3
E Ä?E Å
BG  Ç 
G-Ç,G-Ê(J= Ê=
K
Ë	K
úOptional[list[str]]c                óö  — 	 ddl m}m} n# t          $ r Y dS w xY w |¦   «         }|sdS ddi} ||¦  «        r,d|› �|d<   ddl m}m} d	                     ||z   ¦  «        |d
<   n||d<   t          j         	                    d|¬¦  «        }	 t          j         
                    || ¬¦  «        5 }t          j        |                     ¦   «                              ¦   «         ¦  «        }	d„ |	                     dg ¦  «        D ¦   «         }
t!          |
d„ ¬¦  «        cddd¦  «         S # 1 swxY w Y   dS # t"          $ r=}ddl}|                     t(          ¦  «                             d|¦  «         Y d}~dS d}~ww xY w)zÌFetch available models from the Anthropic /v1/models endpoint.

    Uses resolve_anthropic_token() to find credentials (env vars or
    Claude Code auto-discovery).  Returns sorted model IDs or None.
    r   )Úresolve_anthropic_tokenÚ_is_oauth_tokenNúanthropic-versionú
2023-06-01r¥   r§   )Ú_COMMON_BETASÚ_OAUTH_ONLY_BETASú,zanthropic-betaú	x-api-keyz#https://api.anthropic.com/v1/modelsr©   r¬   c                óH   — g | ]}|                      d ¦  «        ¯|d          ‘Œ S ©rI  ©r™   ró  s     rE   rŽ   z+_fetch_anthropic_models.<locals>.<listcomp>l  s+   € ÐKÐKÐK !¸q¿uºuÀT¹{¼{ÐK�a˜”gÐKÐKÐKrG   rê   c                ó   — d| vd| vd| v| fS )NÚopusÚsonnetÚhaikur‰   )rô  s    rE   ú<lambda>z)_fetch_anthropic_models.<locals>.<lambda>n  s#   € Ø˜a�Ø Ð!Ø˜qÐ Øð	1€ rG   )r  z$Failed to fetch Anthropic models: %s)Úagent.anthropic_adapterrb  rc  ÚImportErrorrf  rg  Újoinr¯   r°   r±   r²   r³   r´   rµ   r¶   r™   Úsortedr·   ÚloggingÚ	getLoggerr	  Údebug)r­   rb  rc  Útokenrª   rf  rg  rº   r»   rê   r6  Úerv  s                rE   r[  r[  N  s3  € ðØTÐTÐTÐTÐTÐTÐTÐTÐTøÝð ð ð Øˆtˆtðøøøð $Ð#Ñ%Ô%€EØð Øˆtà2°LÐA€GØ€�uÑÔð %Ø#4¨UÐ#4Ð#4ˆ�Ñ ØLÐLÐLÐLÐLÐLÐLÐLØ$'§H¢H¨]Ð=NÑ-NÑ$OÔ$OˆÐ Ñ!Ð!à$ˆ�Ñå
Œ.×
 Ò
 Ø-Øð !ñ ô €CðÝŒ^×#Ò# C°Ð#Ñ9Ô9ð 		¸TÝ”:˜dŸiši™kœk×0Ò0Ñ2Ô2Ñ3Ô3ˆDØKÐK t§x¢x°¸Ñ';Ô';ÐKÑKÔKˆFå˜&ð 'ð 'ð ñ ô ð			ð 		ð 		ð 		ñ 		ô 		ð 		ð 		ð 		ð 		ð 		ð 		øøøð 		ð 		ð 		ð 		ð 		ð 		øõ ð ð ð ØˆˆˆØ×Ò�(Ñ#Ô#×)Ò)Ð*PÐRSÑTÔTÐTØˆtˆtˆtˆtˆtøøøøðøøøsI   ‚ ‹
˜Â!D1 Â-A*D$ÄD1 Ä$D(Ä(D1 Ä+D(Ä,D1 Ä1
E8Ä;2E3Å3E8ré   úlist[dict[str, Any]]c                óà   — t          | t          ¦  «        rd„ | D ¦   «         S t          | t          ¦  «        r7|                      dg ¦  «        }t          |t          ¦  «        rd„ |D ¦   «         S g S )Nc                ó<   — g | ]}t          |t          ¦  «        ¯|‘ŒS r‰   ©rÁ   rÂ   ©r‹   r>  s     rE   rŽ   z"_payload_items.<locals>.<listcomp>|  s'   € ÐCÐCÐC˜­J°t½TÑ,BÔ,BÐC�ÐCÐCÐCrG   rê   c                ó<   — g | ]}t          |t          ¦  «        ¯|‘ŒS r‰   r~  r  s     rE   rŽ   z"_payload_items.<locals>.<listcomp>€  s'   € ÐDÐDÐD˜T­Z¸½dÑ-CÔ-CÐD�DÐDÐDÐDrG   )rÁ   rD   rÂ   r™   )ré   rê   s     rE   Ú_payload_itemsr�  z  s{   € Ý�'�4Ñ Ô ð DØCÐC ÐCÑCÔCÐCÝ�'�4Ñ Ô ð EØ�{Š{˜6 2Ñ&Ô&ˆÝ�d�DÑ!Ô!ð 	EØDÐD TÐDÑDÔDÐDØ€IrG   údict[str, str]c                 ó`   — 	 ddl m}   | d¬¦  «        S # t          $ r t          ddddœcY S w xY w)	z Standard headers for Copilot API requests.

    Includes Openai-Intent and x-initiator headers that opencode and the
    Copilot CLI send on every request.
    r   ©Úcopilot_request_headersT)Úis_agent_turnzHermesAgent/1.0zconversation-editsÚagent)zEditor-Versionr«  zOpenai-Intentzx-initiator)Úhermes_cli.copilot_authr…  rs  ÚCOPILOT_EDITOR_VERSIONr„  s    rE   Úcopilot_default_headersrŠ  „  sm   € ð	
ØCÐCÐCÐCÐCÐCØ&Ð&°TÐ:Ñ:Ô:Ð:øÝð 
ð 
ð 
å4Ø+Ø1Ø"ð	
ð 
ð 	
ð 	
ð 	
ð
øøøs   ‚ ”-¬-c                óF  — t          |                      d¦  «        pd¦  «                             ¦   «         }|sdS |                      d¦  «        du rdS |                      d¦  «        }t          |t          ¦  «        rRt          |                     d¦  «        pd¦  «                             ¦   «                              ¦   «         }|r|dk    rdS |                      d¦  «        }t          |t          ¦  «        r'd	„ |D ¦   «         }|r|                     h d
£¦  «        sdS dS )NrI  r   FÚmodel_picker_enabledÚcapabilitiesÚtypeÚchatÚsupported_endpointsc                ó’   — h | ]D}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «         ’ŒES r‰   ©r‘   rî   ©r‹   Úendpoints     rE   rü  z6_copilot_catalog_item_is_text_model.<locals>.<setcomp>¦  sR   € ð  
ð  
ð  
àÝ�8‰}Œ}×"Ò"Ñ$Ô$ð 
Ý�‰MŒM×ÒÑ!Ô!ð 
ð  
ð  
rG   >   ú
/responsesú/v1/messagesú/chat/completionsT)r‘   r™   rî   rÁ   rÂ   râ  rD   Úintersection)r>  r�   r�  Ú
model_typer�  Únormalized_endpointss         rE   Ú#_copilot_catalog_item_is_text_modelr›  –  sB  € Ý�4—8’8˜D‘>”>Ð' RÑ(Ô(×.Ò.Ñ0Ô0€HØð Øˆuà‡x‚xÐ&Ñ'Ô'¨5Ð0Ð0Øˆuà—8’8˜NÑ+Ô+€LÝ�,¥Ñ%Ô%ð Ý˜×)Ò)¨&Ñ1Ô1Ð7°RÑ8Ô8×>Ò>Ñ@Ô@×FÒFÑHÔHˆ
Øð 	˜*¨Ò.Ð.Ø�5àŸ(š(Ð#8Ñ9Ô9ÐÝÐ%¥tÑ,Ô,ð 	ð 
ð  
à/ð 
ñ  
ô  
Ðð
  ð 	Ð(<×(IÒ(IØ?Ð?Ð?ñ)
ô )
ð 	ð �5àˆ4rG   úOptional[list[dict[str, Any]]]c                ó`  — g }| r*|                      i t          ¦   «         ¥dd| › �i¥¦  «         |                      t          ¦   «         ¦  «         |D �]Z}t          j                             t
          |¬¦  «        }	 t          j                             ||¬¦  «        5 }t          j        | 	                    ¦   «          
                    ¦   «         ¦  «        }t          |¦  «        }g }t          ¦   «         }	|D ]y}
t          |
¦  «        sŒt          |
                     d¦  «        pd¦  «                             ¦   «         }|r||	v rŒO|	                     |¦  «         |                      |
¦  «         Œz|r|cddd¦  «         c S 	 ddd¦  «         n# 1 swxY w Y   �ŒK# t$          $ r Y �ŒXw xY wdS )z=Fetch the live GitHub Copilot model catalog for this account.r§   r¥   r©   r¬   rI  r   N)rÊ   rŠ  r¯   r°   r±   ÚCOPILOT_MODELS_URLr²   r³   r´   rµ   r¶   r�  rJ  r›  r‘   r™   rî   rK  r·   )r§  r­   Úattemptsrª   rº   r»   rê   rl  r6  Úseen_idsr>  r�   s               rE   Úfetch_github_model_catalogr¡  ³  s7  € ð &(€HØð Ø�Šð 
Ý%Ñ'Ô'ð
àÐ0 wÐ0Ð0ð
ð 
ñ 	ô 	ð 	ð ‡O‚OÕ+Ñ-Ô-Ñ.Ô.Ð.àð ñ ˆÝŒn×$Ò$Õ%7ÀÐ$ÑIÔIˆð	Ý”×'Ò'¨°WÐ'Ñ=Ô=ð "ÀÝ”z $§)¢)¡+¤+×"4Ò"4Ñ"6Ô"6Ñ7Ô7�Ý& tÑ,Ô,�Ø/1�Ý%(¡U¤U�Ø!ð (ð (�DÝ>¸tÑDÔDð !Ø Ý" 4§8¢8¨D¡>¤>Ð#7°RÑ8Ô8×>Ò>Ñ@Ô@�HØ#ð ! x°8Ð';Ð';Ø Ø—L’L Ñ*Ô*Ð*Ø—M’M $Ñ'Ô'Ð'Ð'Øð "Ø!ð"ð "ð "ð "ñ "ô "ð "ð "ð "ð "ð"ð"ð "ð "ñ "ô "ð "ð "ð "ð "ð "ð "øøøð "ð "ð "ð "ùøõ ð 	ð 	ð 	Ø‰Hð	øøøàˆ4s=   Á<!FÂCFÅ4FÆFÆF	ÆFÆF	ÆFÆ
F+Æ*F+zdict[str, int]Ú_copilot_context_cacheg        Ú_copilot_context_cache_timei  úOptional[int]c                óJ  — t           r<t          j        ¦   «         t          z
  t          k     r| t           v rt           |          S dS t	          |¬¦  «        }|sdS i }|D ]ž}t          |                     d¦  «        pd¦  «                             ¦   «         }|sŒ;|                     d¦  «        pi }|                     d¦  «        pi }|                     d¦  «        }t          |t          ¦  «        r|dk    r|||<   ŒŸ|a t          j        ¦   «         a|                     | ¦  «        S )	zÊLook up max_prompt_tokens for a Copilot model from the live /models API.

    Results are cached in-process for 1 hour to avoid repeated API calls.
    Returns the token limit or None if not found.
    N©r§  rI  r   r�  ÚlimitsÚmax_prompt_tokensr   )
r¢  r×   r£  Ú_COPILOT_CONTEXT_CACHE_TTLr¡  r‘   r™   rî   rÁ   rÏ   )	r�   r§  ÚcatalogrŸ  r>  rŒ   Úcapsr§  Ú
max_prompts	            rE   Úget_copilot_model_contextr­  Þ  s+  € õ ð ¥4¤9¡;¤;Õ1LÑ#LÕOiÒ#iÐ#iØÕ-Ð-Ð-Ý)¨(Ô3Ð3àˆtõ )°Ð9Ñ9Ô9€GØð Øˆtà€EØð $ð $ˆÝ�$—(’(˜4‘.”.Ð& BÑ'Ô'×-Ò-Ñ/Ô/ˆØð 	ØØ�xŠx˜Ñ'Ô'Ð-¨2ˆØ—’˜(Ñ#Ô#Ð) rˆØ—Z’ZÐ 3Ñ4Ô4ˆ
Ý�j¥#Ñ&Ô&ð 	$¨:¸ª>¨>Ø#ˆE�#‰Jøà"ÐÝ"&¤)¡+¤+Ðà�9Š9�XÑÔÐrG   c                óÖ   — | pd                      ¦   «                              d¦  «                             ¦   «         }|                     t          ¦  «        p|                     d¦  «        S )Nr   r¤   z"https://models.github.ai/inference)rî   r®   râ  rf  ÚCOPILOT_BASE_URL)r©  rÁ  s     rE   Ú_is_github_models_base_urlr°    s`   € Ø�.˜b×'Ò'Ñ)Ô)×0Ò0°Ñ5Ô5×;Ò;Ñ=Ô=€Jà×ÒÕ.Ñ/Ô/ð 	GØ× Ò Ð!EÑFÔFðrG   c                óD   — t          | |¬¦  «        }|sd S d„ |D ¦   «         S )N©r§  r­   c                ód   — g | ]-}|                      d ¦  «        ¯|                      d d¦  «        ‘Œ.S ©rI  r   rl  r  s     rE   rŽ   z(_fetch_github_models.<locals>.<listcomp>  s5   € ÐEÐEÐE 4°d·h²h¸t±n´nÐEˆD�HŠH�T˜2ÑÔÐEÐEÐErG   )r¡  )r§  r­   rª  s      rE   rY  rY    s5   € Ý(°À'ÐJÑJÔJ€GØð ØˆtØEÐE¨7ÐEÑEÔEÐErG   zopenai/gpt-5rM   zopenai/gpt-5-chatzopenai/gpt-5-minizopenai/gpt-5-nanozopenai/gpt-4.1rP   zopenai/gpt-4.1-minizopenai/gpt-4.1-nanozopenai/gpt-4orQ   zopenai/gpt-4o-minirR   ú	openai/o1ru   zopenai/o1-minizopenai/o1-previewú	openai/o3rN   zopenai/o3-minizopenai/o4-minir   r   rV   rW   rX   rY   )zanthropic/claude-sonnet-4r   r   ro   rp   zclaude-sonnet-4-0rx   ry   zanthropic/claude-opus-4-6zanthropic/claude-sonnet-4-6zanthropic/claude-sonnet-4-0zanthropic/claude-sonnet-4-5zanthropic/claude-haiku-4-5rª  c                ób   — | €|rt          |¬¦  «        } | st          ¦   «         S d„ | D ¦   «         S )Nr¦  c                óæ   — h | ]n}t          |                     d ¦  «        pd¦  «                             ¦   «         ¯8t          |                     d ¦  «        pd¦  «                             ¦   «         ’ŒoS r´  )r‘   r™   rî   r  s     rE   rü  z'_copilot_catalog_ids.<locals>.<setcomp>A  st   € ð ð ð àÝˆt�xŠx˜‰~Œ~Ð# Ñ$Ô$×*Ò*Ñ,Ô,ðÝˆD�HŠH�T‰NŒNÐ ˜bÑ!Ô!×'Ò'Ñ)Ô)ðð ð rG   )r¡  rJ  ©rª  r§  s     rE   Ú_copilot_catalog_idsrº  9  sO   € ð €˜7€Ý,°WÐ=Ñ=Ô=ˆØð Ý‰uŒuˆðð àðñ ô ð rG   r¹  c               óp  — t          | pd¦  «                             ¦   «         }|sdS t          ||¬¦  «        }t                               |¦  «        }|r|S |g}d|v rA|                     |                     dd¦  «        d                              ¦   «         ¦  «         |                     d¦  «        r|                     |d d…         ¦  «         |                     d¦  «        r|                     |d d…         ¦  «         |                     d¦  «        r|                     |d d…         ¦  «         t          ¦   «         }|D ]>}|r||v rŒ	| 	                    |¦  «         |t          v rt          |         c S ||v r|c S Œ?d|v r.|                     dd¦  «        d                              ¦   «         S |S )	Nr   r¹  r¤   r‡  z-miniéûÿÿÿz-nanoz-chat)
r‘   rî   rº  Ú_COPILOT_MODEL_ALIASESr™   rÊ   r   rÀ  rJ  rK  )	r�   rª  r§  rÝ  Úcatalog_idsrÕ  r   ÚseenÚ	candidates	            rE   Únormalize_copilot_model_idrÁ  H  sà  € õ ˆhˆn˜"Ñ
Ô
×
#Ò
#Ñ
%Ô
%€CØð Øˆrå&¨wÀÐHÑHÔH€KÝ"×&Ò& sÑ+Ô+€EØð Øˆà�€JØ
ˆc€z€zØ×Ò˜#Ÿ)š) C¨Ñ+Ô+¨AÔ.×4Ò4Ñ6Ô6Ñ7Ô7Ð7à
‡|‚|�GÑÔð $Ø×Ò˜#˜c˜r˜cœ(Ñ#Ô#Ð#Ø
‡|‚|�GÑÔð $Ø×Ò˜#˜c˜r˜cœ(Ñ#Ô#Ð#Ø
‡|‚|�GÑÔð $Ø×Ò˜#˜c˜r˜cœ(Ñ#Ô#Ð#å‘U”U€DØð ð ˆ	Øð 	˜I¨Ð-Ð-ØØ�Š�ÑÔÐØÕ.Ð.Ð.Ý)¨)Ô4Ð4Ð4Ð4Ø˜Ð#Ð#ØÐÐÐð $ð ˆc€z€zØ�yŠy˜˜aÑ Ô  Ô#×)Ò)Ñ+Ô+Ð+Ø€JrG   c                ó<  — | pd                      ¦   «                              ¦   «         }|                     d¦  «        rt          t          ¦  «        S t          | ¦  «                             ¦   «         }|                     d¦  «        rt          t          ¦  «        S g S )Nr   )rµ  r¶  z	openai/o4Úo1r*  Úo4rw   )rî   râ  rf  rD   Ú"COPILOT_REASONING_EFFORTS_O_SERIESrÁ  ÚCOPILOT_REASONING_EFFORTS_GPT5)r�   rÝ  rÁ  s      rE   Ú&_github_reasoning_efforts_for_model_idrÇ  q  sŠ   € Øˆ>�r×
 Ò
 Ñ
"Ô
"×
(Ò
(Ñ
*Ô
*€CØ
‡~‚~ÐOÑPÔPð 8ÝÕ6Ñ7Ô7Ð7Ý+¨HÑ5Ô5×;Ò;Ñ=Ô=€JØ×Ò˜WÑ%Ô%ð 4ÝÕ2Ñ3Ô3Ð3Ø€IrG   c                óº   — ddl }|                     d| ¦  «        }|sdS t          |                     d¦  «        ¦  «        }|dk    o|                      d¦  «         S )a%  Decide whether a Copilot model should use the Responses API.

    Replicates opencode's ``shouldUseCopilotResponsesApi`` logic:
    GPT-5+ models use Responses API, except ``gpt-5-mini`` which uses
    Chat Completions.  All non-GPT models (Claude, Gemini, etc.) use
    Chat Completions.
    r   Nz
^gpt-(\d+)Fr‡  rŽ  rM   )ÚreÚmatchrÏ   Úgrouprf  )r�   rÉ  rÊ  Úmajors       rE   Ú!_should_use_copilot_responses_apirÍ  {  sd   € ð €I€I€Ià�HŠH�] HÑ-Ô-€EØð ØˆuÝ�—’˜A‘”ÑÔ€EØ�AŠ:Ð?˜h×1Ò1°,Ñ?Ô?Ð?Ð?rG   c               ó:  ‡— |€|rt          |¬¦  «        }t          | ||¬¦  «        Š‰sdS t          ‰¦  «        rdS |r\t          ˆfd„|D ¦   «         d¦  «        }t	          |t
          ¦  «        r+d„ |                     d¦  «        pg D ¦   «         }d	|v rd
|vrdS dS )zôDetermine the API mode for a Copilot model.

    Uses the model ID pattern (matching opencode's approach) as the
    primary signal.  Falls back to the catalog's ``supported_endpoints``
    only for models not covered by the pattern check.
    Nr¦  r¹  Úchat_completionsÚcodex_responsesc              3  óN   •K  — | ]}|                      d ¦  «        ‰k    ¯|V — Œ dS ©rI  Nrl  ©r‹   r>  rÁ  s     €rE   rg  z)copilot_model_api_mode.<locals>.<genexpr>§  ó7   øè è € ÐWÐW t¸$¿(º(À4¹.¼.ÈJÒ:VÐ:V˜dÐ:VÐ:VÐ:VÐ:VÐWÐWrG   c                ó’   — h | ]D}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «         ’ŒES r‰   r’  r“  s     rE   rü  z)copilot_model_api_mode.<locals>.<setcomp>©  sR   € ð #ð #ð #àÝ�x‘=”=×&Ò&Ñ(Ô(ð#Ý�H‘”×#Ò#Ñ%Ô%ð#ð #ð #rG   r�  r–  r—  Úanthropic_messages)r¡  rÁ  rÍ  rk  rÁ   rÂ   r™   )r�   rª  r§  Úcatalog_entryr�  rÁ  s        @rE   Úcopilot_model_api_moderØ  Œ  sò   ø€ ð €˜7€Ý,°WÐ=Ñ=Ô=ˆå+¨H¸gÈwÐWÑWÔW€JØð "Ø!Ð!õ )¨Ñ4Ô4ð !Ø Ð ð ð 
,ÝÐWÐWÐWÐW¨wÐWÑWÔWÐY]Ñ^Ô^ˆÝ�m¥TÑ*Ô*ð 	,ð#ð #à!.×!2Ò!2Ð3HÑ!IÔ!IÐ!OÈRð#ñ #ô #Ðð Ð!4Ð4Ð4Ð9LÐTgÐ9gÐ9gØ+Ð+àÐrG   Úprovider_idc                ó   — t          | ¦  «        }t          |pd¦  «                             ¦   «         }|r|dvr|S |› d�}|                     ¦   «                              |¦  «        r|t          |¦  «        d…         S |S )zJNormalize OpenCode config IDs to the bare model slug used in API requests.r   >   r�   r€   r¤   N)r¿  r‘   rî   râ  rf  r‚  )rÙ  r�   r4  Úcurrentr  s        rE   Únormalize_opencode_model_idrÜ  µ  s‡   € å! +Ñ.Ô.€HÝ�(�.˜bÑ!Ô!×'Ò'Ñ)Ô)€GØð �hÐ&EÐEÐEØˆàˆ^ˆ^ˆ^€FØ‡}‚}�„×!Ò! &Ñ)Ô)ð %Ø•s˜6‘{”{�|�|Ô$Ð$Ø€NrG   c                ó  — t          | ¦  «        }t          | |¦  «                             ¦   «         }|sdS |dk    r|                     d¦  «        rdS dS |dk    r0|                     d¦  «        rdS |                     d¦  «        rdS dS dS )	aø  Determine the API mode for an OpenCode Zen / Go model.

    OpenCode routes different models behind different API surfaces:

    - GPT-5 / Codex models on Zen use ``/v1/responses``
    - Claude models on Zen use ``/v1/messages``
    - MiniMax models on Go use ``/v1/messages``
    - GLM / Kimi on Go use ``/v1/chat/completions``
    - Other Zen models (Gemini, GLM, Kimi, MiniMax, Qwen, etc.) use
      ``/v1/chat/completions``

    This follows the published OpenCode docs for Zen and Go endpoints.
    rÏ  r�   zminimax-rÖ  r€   zclaude-zgpt-rÐ  )r¿  rÜ  râ  rf  )rÙ  r�   r4  rÁ  s       rE   Úopencode_model_api_moderÞ  Â  s¶   € õ " +Ñ.Ô.€HÝ,¨[¸(ÑCÔC×IÒIÑKÔK€JØð "Ø!Ð!à�=Ò Ð Ø× Ò  Ñ,Ô,ð 	(Ø'Ð'Ø!Ð!à�>Ò!Ð!Ø× Ò  Ñ+Ô+ð 	(Ø'Ð'Ø× Ò  Ñ(Ô(ð 	%Ø$Ð$Ø!Ð!àÐrG   c               óÄ  ‡
— t          | ||¬¦  «        Š
‰
sg S d}|�t          ˆ
fd„|D ¦   «         d¦  «        }n0|r.t          |¬¦  «        }|rt          ˆ
fd„|D ¦   «         d¦  «        }|�Ù|                     d¦  «        }t	          |t
          ¦  «        r‰|                     d¦  «        }t	          |t
          ¦  «        r]|                     d¦  «        }t	          |t          ¦  «        r3d	„ |D ¦   «         }t          t
                               |¦  «        ¦  «        S g S d
„ |                     dg ¦  «        D ¦   «         }	d|	vrg S t          t          | p‰
¦  «        ¦  «        S )zEReturn supported reasoning-effort levels for a Copilot-visible model.r¹  Nc              3  óN   •K  — | ]}|                      d ¦  «        ‰k    ¯|V — Œ dS rÒ  rl  rÓ  s     €rE   rg  z1github_model_reasoning_efforts.<locals>.<genexpr>ñ  rÔ  rG   r¦  c              3  óN   •K  — | ]}|                      d ¦  «        ‰k    ¯|V — Œ dS rÒ  rl  rÓ  s     €rE   rg  z1github_model_reasoning_efforts.<locals>.<genexpr>õ  s8   øè è € Ð!cÐ!c¨4ÀdÇhÂhÈtÁnÄnÐXbÒFbÐFb $ÐFbÐFbÐFbÐFbÐ!cÐ!crG   r�  ÚsupportsÚreasoning_effortc                ó¶   — g | ]V}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «                              ¦   «         ‘ŒWS r‰   ©r‘   rî   râ  )r‹   Úefforts     rE   rŽ   z2github_model_reasoning_efforts.<locals>.<listcomp>þ  s^   € ð *ð *ð *à"Ý˜v™;œ;×,Ò,Ñ.Ô.ð*Ý˜F™œ×)Ò)Ñ+Ô+×1Ò1Ñ3Ô3ð*ð *ð *rG   c                ó¶   — h | ]V}t          |¦  «                             ¦   «         ¯#t          |¦  «                             ¦   «                              ¦   «         ’ŒWS r‰   rå  )r‹   Ú
capabilitys     rE   rü  z1github_model_reasoning_efforts.<locals>.<setcomp>	  s^   € ð 
ð 
ð 
àÝ�:‰Œ×$Ò$Ñ&Ô&ð
Ý�
‰OŒO×!Ò!Ñ#Ô#×)Ò)Ñ+Ô+ð
ð 
ð 
rG   Ú	reasoning)
rÁ  rk  r¡  r™   rÁ   rÂ   rD   ÚfromkeysrÇ  r‘   )r�   rª  r§  r×  Úfetched_catalogr�  râ  ÚeffortsÚnormalized_effortsÚlegacy_capabilitiesrÁ  s             @rE   Úgithub_model_reasoning_effortsrï  ä  s³  ø€ õ ,¨H¸gÈwÐWÑWÔW€JØð Øˆ	à€MØÐÝÐWÐWÐWÐW¨wÐWÑWÔWÐY]Ñ^Ô^ˆˆØ	ð kÝ4¸WÐEÑEÔEˆØð 	kÝ Ð!cÐ!cÐ!cÐ!c°?Ð!cÑ!cÔ!cÐeiÑjÔjˆMàÐ Ø$×(Ò(¨Ñ8Ô8ˆÝ�l¥DÑ)Ô)ð 	Ø#×'Ò'¨
Ñ3Ô3ˆHÝ˜(¥DÑ)Ô)ð CØ"Ÿ,š,Ð'9Ñ:Ô:�Ý˜g¥tÑ,Ô,ð Cð*ð *à&-ð*ñ *ô *Ð&õ
  ¥§¢Ð.@Ñ AÔ AÑBÔBÐBØˆIð
ð 
à+×/Ò/°ÀÑCÔCð
ñ 
ô 
Ðð
 Ð1Ð1Ð1ØˆIå1µ#°hÐ6LÀ*Ñ2MÔ2MÑNÔNÐNrG   Úapi_modec                óæ  — |pd                      ¦   «                              d¦  «        }|sddddddœS t          |¦  «        r#t          | |¬¦  «        }|t          t
          dddœS |                     d¦  «        r|dd…                              d¦  «        }n|dz   }|dfg}|r||k    r|                     |d	f¦  «         g }d
t          i}	| r|dk    r| |	d<   d|	d<   n
| rd| › �|	d<   | 	                    t
          ¦  «        r!|	 
                    t          ¦   «         ¦  «         |D �]\  }
}|
                     d¦  «        dz   }|                     |¦  «         t          j                             ||	¬¦  «        }	 t          j                             ||¬¦  «        5 }t!          j        |                     ¦   «                              ¦   «         ¦  «        }d„ |                     dg ¦  «        D ¦   «         ||
                     d¦  «        ||
k    r|n||dœcddd¦  «         c S # 1 swxY w Y   �Œ# t*          $ r Y �Œw xY wd|r|d         n|                     d¦  «        dz   |||k    r|ndddœS )a8  Probe a ``/models`` endpoint with light URL heuristics.

    For ``anthropic_messages`` mode, uses ``x-api-key`` and
    ``anthropic-version`` headers (Anthropic's native auth) instead of
    ``Authorization: Bearer``.  The response shape (``data[].id``) is
    identical, so the same parser works for both.
    r   r¤   NF)r6  Ú
probed_urlÚresolved_base_urlÚsuggested_base_urlÚused_fallbackr²  r½  r¾  Tr«  rÖ  ri  re  rd  r¥   r§   r
   r©   r¬   c                ó:   — g | ]}|                      d d¦  «        ‘ŒS r´  rl  ró  s     rE   rŽ   z$probe_api_models.<locals>.<listcomp>L	  s$   € ÐMÐMÐM°1˜qŸušu T¨2™œÐMÐMÐMrG   rê   r   )rî   r®   r°  rY  rž  r¯  rÀ  rÊ   r®  rf  ÚupdaterŠ  r¯   r°   r±   r²   r³   r´   rµ   r¶   r™   r·   )r§  r©  r­   rð  rÁ  r6  Úalternate_baser   Útriedrª   Úcandidate_baseÚis_fallbackr¹   rº   r»   rê   s                   rE   Úprobe_api_modelsrü  	  sO  € ð �.˜b×'Ò'Ñ)Ô)×0Ò0°Ñ5Ô5€JØð 
àØØ!#Ø"&Ø"ð
ð 
ð 	
õ " *Ñ-Ô-ð 
Ý%¨g¸wÐGÑGÔGˆàÝ,Ý!1Ø"&Ø"ð
ð 
ð 	
ð ×Ò˜5Ñ!Ô!ð ,Ø# C R Cœ×/Ò/°Ñ4Ô4ˆˆà# eÑ+ˆà+5°uÐ*=Ð)>€JØð 2˜.¨JÒ6Ð6Ø×Ò˜>¨4Ð0Ñ1Ô1Ð1à€EØ+Õ-?Ð@€GØð 7�8Ð3Ò3Ð3Ø&ˆ�ÑØ'3ˆÐ#Ñ$Ð$Ø	ð 7Ø#6¨WÐ#6Ð#6ˆ�Ñ Ø×ÒÕ-Ñ.Ô.ð 2Ø�ŠÕ.Ñ0Ô0Ñ1Ô1Ð1à'1ð ñ Ñ#ˆ˜Ø×#Ò# CÑ(Ô(¨9Ñ4ˆØ�Š�SÑÔÐÝŒn×$Ò$ S°'Ð$Ñ:Ô:ˆð	Ý”×'Ò'¨°WÐ'Ñ=Ô=ð ÀÝ”z $§)¢)¡+¤+×"4Ò"4Ñ"6Ô"6Ñ7Ô7�àMÐM¸¿ºÀÈÑ8LÔ8LÐMÑMÔMØ"%Ø)7×)>Ò)>¸sÑ)CÔ)CØ<JÈnÒ<\Ð<\¨.¨.ÐblØ%0ðð ðð ð ð ñ ô ð ð ð ð ð ð ð ð øøøð ð ð ð ñ øõ ð 	ð 	ð 	Ø‰Hð	øøøð Ø"'ÐO�e˜A”h�h¨Z×->Ò->¸sÑ-CÔ-CÀiÑ-OØ'Ø0>À*Ò0LÐ0L˜n˜nÐRVØðð ð s7   Å<!H2ÆA9H%ÈH2È%H)	È)H2È,H)	È-H2È2
I È?I c                ó�  — t          j        dd¦  «                             ¦   «         }|sdS t          j        dd¦  «                             ¦   «         }|sddlm} |}|                     d¦  «        dz   }d	|› �t          d
œ}t          j         	                    ||¬¦  «        }	 t          j         
                    || ¬¦  «        5 }t          j        |                     ¦   «                              ¦   «         ¦  «        }d„ |                     dg ¦  «        D ¦   «         cddd¦  «         S # 1 swxY w Y   dS # t           $ r Y dS w xY w)z>Fetch available language models with tool-use from AI Gateway.ÚAI_GATEWAY_API_KEYr   Nrc  r   rb  r¤   r
   r¥   )r§   r«  r©   r¬   c                ó¬   — g | ]Q}|                      d ¦  «        r:|                      d¦  «        dk    r!d|                      d¦  «        pg v ¯I|d          ‘ŒRS )rI  rŽ  Úlanguageztool-useÚtagsrl  ró  s     rE   rŽ   z,_fetch_ai_gateway_models.<locals>.<listcomp>q	  sk   € ð ð ð àØ—5’5˜‘;”;ðð —E’E˜&‘M”M ZÒ/Ð/Ø 1§5¢5¨¡=¤=Ð#6°BÐ7Ð7ð	 �$”ð 8Ð7Ð7rG   rê   )rµ  r¶  rî   rj  rc  r®   r®  r¯   r°   r±   r²   r³   r´   rµ   r¶   r™   r·   )	r­   r§  r©  rc  r¹   rª   rº   r»   rê   s	            rE   r\  r\  ^	  s¨  € åŒiÐ,¨bÑ1Ô1×7Ò7Ñ9Ô9€GØð ØˆtÝŒyÐ.°Ñ3Ô3×9Ò9Ñ;Ô;€HØð 'Ø8Ð8Ð8Ð8Ð8Ð8Ø&ˆà
�/Š/˜#Ñ
Ô
 Ñ
*€Cà, 7Ð,Ð,Ý(ðð €Gõ Œ.×
 Ò
  ¨gÐ
 Ñ
6Ô
6€CðÝŒ^×#Ò# C°Ð#Ñ9Ô9ð 	¸TÝ”:˜dŸiši™kœk×0Ò0Ñ2Ô2Ñ3Ô3ˆDðð àŸš &¨"Ñ-Ô-ðñ ô ð	ð 	ð 	ð 	ñ 	ô 	ð 	ð 	ð 	ð 	ð 	ð 	øøøð 	ð 	ð 	ð 	ð 	ð 	øõ ð ð ð Øˆtˆtðøøøs7   Â$!D7 ÃAD*ÄD7 Ä*D.Ä.D7 Ä1D.Ä2D7 Ä7
EÅEc                óN   — t          | |||¬¦  «                             d¦  «        S )zàFetch the list of available model IDs from the provider's ``/models`` endpoint.

    Returns a list of model ID strings, or ``None`` if the endpoint could not
    be reached (network error, timeout, auth failure, etc.).
    )r­   rð  r6  )rü  r™   )r§  r©  r­   rð  s       rE   rZ  rZ  |	  s*   € õ ˜G X°wÈÐRÑRÔR×VÒVÐW_Ñ`Ô`Ð`rG   r   c                 ó(   — ddl m}   | ¦   «         dz  S )z1Return the path for the Ollama Cloud model cache.r   ©Úget_hermes_homezollama_cloud_models_cache.json)rj  r  r  s    rE   Ú_ollama_cloud_cache_pathr  “	  s(   € à0Ð0Ð0Ð0Ð0Ð0Øˆ?ÑÔÐ?Ñ?Ð?rG   ©Ú
ignore_ttlr  úOptional[dict]c                óê  — 	 t          ¦   «         }|                     ¦   «         sdS t          |d¬¦  «        5 }t          j        |¦  «        }ddd¦  «         n# 1 swxY w Y   t          |t          ¦  «        sdS |                     d¦  «        }t          |t          ¦  «        r|sdS | s7|                     dd¦  «        }t          j	        ¦   «         |z
  t          k    rdS |S # t          $ r Y nw xY wdS )z‘Load cached Ollama Cloud models from disk.

    Args:
        ignore_ttl: If True, return data even if the TTL has expired (stale fallback).
    Nzutf-8)Úencodingr6  rÜ   r   )r  ÚexistsÚopenr³   ÚloadrÁ   rÂ   r™   rD   r×   Ú_OLLAMA_CLOUD_CACHE_TTLr·   )r  Ú
cache_pathÚfrê   r6  rÜ   s         rE   Ú_load_ollama_cloud_cacher  ™	  sD  € ðÝ-Ñ/Ô/ˆ
Ø× Ò Ñ"Ô"ð 	Ø�4Ý�* wÐ/Ñ/Ô/ð 	 °1Ý”9˜Q‘<”<ˆDð	 ð 	 ð 	 ñ 	 ô 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 øøøð 	 ð 	 ð 	 ð 	 å˜$¥Ñ%Ô%ð 	Ø�4Ø—’˜(Ñ#Ô#ˆÝ˜6¥4Ñ(Ô(ð 	¨Vð 	Ø�4Øð 	ØŸš ¨aÑ0Ô0ˆIÝ”	‘”˜iÑ'Õ+BÒBÐBØ�tØˆøÝð ð ð Øˆðøøøàˆ4sK   ‚"C# ¦C# ·AÁC# ÁAÁC# ÁAÁ C# Á:,C# Â(7C# Ã!C# Ã#
C0Ã/C0ÚNonec                óÎ   — 	 ddl m} t          ¦   «         }|j                             dd¬¦  «          ||| t          j        ¦   «         dœd¬¦  «         dS # t          $ r Y dS w xY w)z3Persist the merged Ollama Cloud model list to disk.r   )Úatomic_json_writeT)ÚparentsÚexist_ok)r6  rÜ   N)r}  )Úutilsr  r  ÚparentÚmkdirr×   r·   )r6  r  r  s      rE   Ú_save_ollama_cloud_cacher  ´	  s�   € ðØ+Ð+Ð+Ð+Ð+Ð+Ý-Ñ/Ô/ˆ
ØÔ×Ò¨°tÐÑ<Ô<Ð<ØÐ˜*°ÅdÄiÁkÄkÐ&RÐ&RÐ[_Ð`Ñ`Ô`Ð`Ð`Ð`øÝð ð ð Øˆˆðøøøs   ‚AA Á
A$Á#A$c               ón  — |st          ¦   «         }|�|d         S | st          j        dd¦  «        } |st          j        dd¦  «        pd}g }| rt          | |d¬¦  «        }|r|}g }	 d	d
lm}  |d¦  «        }n# t          $ r Y nw xY w|s|r�t          ¦   «         }g }	|D ]2}
|
r.|
|vr*|                     |
¦  «         |	 	                    |
¦  «         Œ3|D ]2}
|
r.|
|vr*|                     |
¦  «         |	 	                    |
¦  «         Œ3|	rt          |	¦  «         |	S t          d¬¦  «        }|�|d         S g S )uÎ  Fetch Ollama Cloud models by merging live API + models.dev, with disk cache.

    Resolution order:
      1. Disk cache (if fresh, < 1 hour, and not force_refresh)
      2. Live ``/v1/models`` endpoint (primary â€” freshest source)
      3. models.dev registry (secondary â€” fills gaps for unlisted models)
      4. Merge: live models first, then models.dev additions (deduped)

    Returns a list of model IDs (never None â€” empty list on total failure).
    Nr6  ÚOLLAMA_API_KEYr   ÚOLLAMA_BASE_URLzhttps://ollama.com/v1rD  r¬   r   rG  r  Tr  )r  rµ  r¶  rZ  rI  rH  r·   rJ  rK  rÊ   r  )r§  r©  rå   rè   Úlive_modelsrß   Úmdev_modelsrH  r¿  rN  rô  Ústales               rE   r]  r]  ¿	  sÆ  € ð" ð $Ý)Ñ+Ô+ˆØÐØ˜(Ô#Ð#ð ð 2Ý”)Ð,¨bÑ1Ô1ˆØð OÝ”9Ð.°Ñ3Ô3ÐNÐ7Nˆà€KØð !Ý! '¨8¸SÐAÑAÔAˆØð 	!Ø ˆKð  €KðØ8Ð8Ð8Ð8Ð8Ð8Ø)Ð)¨.Ñ9Ô9ˆˆøÝð ð ð Øˆðøøøð ð �kð Ý™œˆØˆØð 	!ð 	!ˆAØð !�Q˜d�]�]Ø—’˜‘”�Ø—’˜aÑ Ô Ð øØð 	!ð 	!ˆAØð !�Q˜d�]�]Ø—’˜‘”�Ø—’˜aÑ Ô Ð øØð 	Ý$ VÑ,Ô,Ð,ØˆMõ %°Ð5Ñ5Ô5€EØÐØ�XŒÐà€Is   Á(A: Á:
BÂB)r§  r©  rð  c          
     óÈ  ‡— | pd                      ¦   «         }t          |¦  «        }|dk    r|rd|vrd}|}|dk    rt          ||¬¦  «        p|}|sddddd	œS t          d
„ |D ¦   «         ¦  «        rddddd	œS |dk    �rz|dk    rt	          |||¬¦  «        }nt	          ||¦  «        }|                     d¦  «        }	|	�×|t          |	¦  «        v rddddd	œS t          ||	dd¬¦  «        }
|
rddd|
d         d|› d|
d         › d�dœS t          ||	dd¬¦  «        }d}|r"dd                     d„ |D ¦   «         ¦  «        z   }d|› d|                     d ¦  «        › d!|› �}|                     d"¦  «        r|d#|                     d$¦  «        › d%�z  }ddd|d	œS d&|                     d ¦  «        › d'|› d(�}|dk    r|d)z  }|                     d*¦  «        r|d+|                     d*¦  «        › d�z  }|dk    dd|d	œS |d,k    r³	 t          d,¦  «        }n# t          $ r g }Y nw xY w|rŽ|t          |¦  «        v rddddd	œS t          ||dd¬¦  «        }
|
rddd|
d         d|› d|
d         › d�dœS t          ||dd¬¦  «        }d}|r"dd                     d-„ |D ¦   «         ¦  «        z   }dddd.|› d/|› �d	œS |d0v �r	 t          |¦  «        }n# t          $ r g }Y nw xY w|réd1„ |D ¦   «         Š|                     ¦   «         ‰v rddddd	œS t          ‰                     ¦   «         ¦  «        }t          |                     ¦   «         |dd¬¦  «        }
|
r‰|
d                  }ddd|d|› d|› d�dœS t          |                     ¦   «         |dd¬¦  «        }d}|r$dd                     ˆfd2„|D ¦   «         ¦  «        z   }dddd|› d3|› d4�d	œS |d5k    ržt          ¦   «         }|�Ž|t          |¦  «        v rddddd	œS t          ||dd¬¦  «        }
|
rddd|
d         d|› d|
d         › d�dœS t          ||dd¬¦  «        }d}|r"dd                     d6„ |D ¦   «         ¦  «        z   }dddd|› d7|› �d	œS |dk    rgt          |||¬¦  «        }	|	�H|t          |	¦  «        v rddddd	œS t          ||	dd¬¦  «        }
|
rddd|
d         d|› d|
d         › d�dœS dddd8|› d9�d	œS t          ||¦  «        }	|	� |d:k    rd;„ |	D ¦   «         }	|t          |	¦  «        v rddddd	œS t          ||	dd¬¦  «        }
|
rddd|
d         d|› d|
d         › d�dœS t          ||	dd¬¦  «        }d}|r"dd                     d<„ |D ¦   «         ¦  «        z   }dddd.|› d=|› �d	œS |d>k    r›	 dd?lm}m}  |¦   «         } ||¦  «        }d@„ |D ¦   «         }||v rddddd	œS t          |t          |¦  «        ddA¬¦  «        }d}|r"dd                     dB„ |D ¦   «         ¦  «        z   }dddd|› dC|› dD|› �d	œS # t          $ r Y nw xY wt&                               ||¦  «        }	 t          |¦  «        }n# t          $ r g }Y nw xY w|rìdE„ |D ¦   «         Š|                     ¦   «         ‰v rddddd	œS t          ‰                     ¦   «         ¦  «        }t          |                     ¦   «         |dd¬¦  «        }
|
r‰|
d                  }ddd|d|› d|› d�dœS t          |                     ¦   «         |dd¬¦  «        }d}|r$dd                     ˆfdF„|D ¦   «         ¦  «        z   }dddd|› dG|› dH|› dI�d	œS ddddJ|› dK|› dL�d	œS )Ma¹  
    Validate a ``/model`` value for the active provider.

    Performs format checks first, then probes the live API to confirm
    the model actually exists.

    Returns a dict with:
      - accepted: whether the CLI should switch to the requested model now
      - persist: whether it is safe to save to config
      - recognized: whether it matched a known provider catalog
      - message: optional warning / guidance for the user
    r   r  zopenrouter.air  rU   r¦  FzModel name cannot be empty.)ÚacceptedÚpersistÚ
recognizedÚmessagec              3  ó>   K  — | ]}|                      ¦   «         V — Œd S r  )Úisspace)r‹   Úchs     rE   rg  z+validate_requested_model.<locals>.<genexpr>(
  s*   è è € Ð
,Ð
,˜Bˆ2�:Š:‰<Œ<Ð
,Ð
,Ð
,Ð
,Ð
,Ð
,rG   z"Model names cannot contain spaces.rÖ  )rð  r6  NTr‡  gÍÌÌÌÌÌì?)ÚnÚcutoffr   zAuto-corrected `u   ` â†’ `ú`)r#  r$  r%  Úcorrected_modelr&  rŒ  g      à?z
  Similar models: z, c              3  ó"   K  — | ]
}d |› d �V — ŒdS ©r,  Nr‰   ©r‹   Úss     rE   rg  z+validate_requested_model.<locals>.<genexpr>N
  ó+   è è € ÐDcÐDcÐRSÀXÈÀXÀXÀXÐDcÐDcÐDcÐDcÐDcÐDcrG   zNote: `z9` was not found in this custom endpoint's model listing (rò  zE). It may still work if the server supports hidden or aliased models.rõ  z1
  Endpoint verification succeeded after trying `ró  z)`. Consider saving that as your base URL.z?Note: could not reach this custom endpoint's model listing at `z`. Hermes will still save `z=`, but the endpoint should expose `/models` for verification.zŽ
  Many Anthropic-compatible proxies do not implement the Models API (GET /v1/models).  The model name has been accepted without verification.rô  z0
  If this server expects `/v1`, try base URL: `rS   c              3  ó"   K  — | ]
}d |› d �V — ŒdS r/  r‰   r0  s     rE   rg  z+validate_requested_model.<locals>.<genexpr>�
  r2  rG   zModel `z2` was not found in the OpenAI Codex model listing.)rk   rm   c                ó8   — i | ]}|                      ¦   «         |“ŒS r‰   r  ró  s     rE   r  z,validate_requested_model.<locals>.<dictcomp>¤
  s"   € ÐBÐBÐB¨a˜QŸWšW™YœY¨ÐBÐBÐBrG   c              3  ó0   •K  — | ]}d ‰|         › d �V — ŒdS r/  r‰   ©r‹   r1  Úcatalog_lowers     €rE   rg  z+validate_requested_model.<locals>.<genexpr>»
  s6   øè è € ÐDrÐDrÐabÐE\ÈÐWXÔIYÐE\ÐE\ÐE\ÐDrÐDrÐDrÐDrÐDrÐDrrG   z'` was not found in the MiniMax catalog.z�
  MiniMax does not expose a /models endpoint, so Hermes cannot verify the model name.
  The model may still work if it exists on the server.rn   c              3  ó"   K  — | ]
}d |› d �V — ŒdS r/  r‰   r0  s     rE   rg  z+validate_requested_model.<locals>.<genexpr>ä
  r2  rG   zn` was not found in Anthropic's /v1/models listing. It may still work if you have early-access or snapshot IDs.zNote: could not verify `z¤` against this endpoint's model listing.  Many Anthropic-compatible proxies do not implement GET /v1/models.  The model name has been accepted without verification.r]   c                ó”   — g | ]E}t          |t          ¦  «        r,|                     d ¦  «        r|t          d ¦  «        d…         n|‘ŒFS )zmodels/N)rÁ   r‘   rf  r‚  ró  s     rE   rŽ   z,validate_requested_model.<locals>.<listcomp>"  s]   € ð ð ð àõ '1°µCÑ&8Ô&8Ð[¸Q¿\º\È)Ñ=TÔ=TÐ[�•#�i‘.”.�/�/Ô"Ð"ÐZ[ðð ð rG   c              3  ó"   K  — | ]
}d |› d �V — ŒdS r/  r‰   r0  s     rE   rg  z+validate_requested_model.<locals>.<genexpr>B  r2  rG   z1` was not found in this provider's model listing.r…   )Údiscover_bedrock_modelsÚresolve_bedrock_regionc                ó   — h | ]
}|d          ’ŒS rk  r‰   ró  s     rE   rü  z+validate_requested_model.<locals>.<setcomp>Y  s   € Ð:Ð:Ð:¨!˜a œgÐ:Ð:Ð:rG   gš™™™™™Ù?c              3  ó"   K  — | ]
}d |› d �V — ŒdS r/  r‰   r0  s     rE   rg  z+validate_requested_model.<locals>.<genexpr>f  r2  rG   z/` was not found in Bedrock model discovery for zK. It may still work with custom inference profiles or cross-account access.c                ó8   — i | ]}|                      ¦   «         |“ŒS r‰   r  ró  s     rE   r  z,validate_requested_model.<locals>.<dictcomp>„  s"   € Ð>Ð>Ð>¨!˜Ÿš™œ AÐ>Ð>Ð>rG   c              3  ó0   •K  — | ]}d ‰|         › d �V — ŒdS r/  r‰   r6  s     €rE   rg  z+validate_requested_model.<locals>.<genexpr>ž  sM   øè è € ð Að AØ,-Ð'�M !Ô$Ð'Ð'Ð'ðAð Að Að Að Að ArG   z` was not found in the z: curated catalog and the /models endpoint was unreachable.z9
  The model may still work if it exists on the provider.zNote: could not reach the z API to validate `z:`. If the service isn't down, this model may not be valid.)rî   r¿  rÁ  r  rü  r™   rJ  r   rt  rö  r·   râ  rD   Úkeysr[  rZ  Úagent.bedrock_adapterr;  r<  rÑ  )rõ   r4  r§  r©  rð  Ú	requestedrÁ  Úrequested_for_lookupÚprobeÚ
api_modelsr#  ÚsuggestionsÚsuggestion_textr&  Úcodex_modelsÚcatalog_modelsÚcatalog_lower_listÚ	correctedÚanthropic_modelsr;  r<  ÚregionÚ
discoveredÚdiscovered_idsr&  r7  s                            @rE   Úvalidate_requested_modelrQ  
  sR  ø€ ð( Ð!˜r×(Ò(Ñ*Ô*€IÝ# HÑ-Ô-€JØ�\Ò!Ð! hÐ!°?È(Ð3RÐ3RØˆ
Ø$ÐØ�YÒÐÝ9ØØð 
ñ  
ô  
ð  ð ð 	ð
 ð 
àØØØ4ð	
ð 
ð 	
õ Ð
,Ð
, )Ð
,Ñ
,Ô
,Ñ,Ô,ð 
àØØØ;ð	
ð 
ð 	
ð �XÒÑàÐ+Ò+Ð+Ý$ W¨hÀÐJÑJÔJˆEˆEå$ W¨hÑ7Ô7ˆEØ—Y’Y˜xÑ(Ô(ˆ
ØÐ!Ø#¥s¨:¡¤Ð6Ð6à $Ø#Ø"&Ø#ð	ð ð õ %Ð%9¸:ÈÐSVÐWÑWÔWˆDØð à $Ø#Ø"&Ø'+¨A¤wØN°)ÐNÐNÀDÈÄGÐNÐNÐNðð ð õ ,¨I°zÀQÈsÐSÑSÔSˆKØ ˆOØð dØ"8¸4¿9º9ÐDcÐDcÐWbÐDcÑDcÔDcÑ;cÔ;cÑ"c�ð%˜)ð %ð %Ø—I’I˜lÑ+Ô+ð%ð %à"ð%ð %ð ð
 �yŠy˜Ñ)Ô)ð Øð>ÈÏÊÐSfÑIgÔIgð >ð >ð >ñ�ð !ØØ#Ø"ð	ð ð ðpÈeÏiÊiÐXdÑNeÔNeð pð pØ'0ðpð pð pð 	ð Ð+Ò+Ð+Øð\ñˆGð �9Š9Ð)Ñ*Ô*ð 	nØÐmÈ5Ï9Ê9ÐUiÑKjÔKjÐmÐmÐmÑmˆGð !Ð$8Ò8ØØØð	
ð 
ð 	
ð �^Ò#Ð#ð	Ý-¨nÑ=Ô=ˆLˆLøÝð 	ð 	ð 	ØˆLˆLˆLð	øøøàð 	Ø#¥s¨<Ñ'8Ô'8Ð8Ð8à $Ø#Ø"&Ø#ð	ð ð õ %Ð%9¸<È1ÐUXÐYÑYÔYˆDØð à $Ø#Ø"&Ø'+¨A¤wØN°)ÐNÐNÀDÈÄGÐNÐNÐNðð ð õ ,Ð,@À,ÐRSÐ\_Ð`Ñ`Ô`ˆKØ ˆOØð dØ"8¸4¿9º9ÐDcÐDcÐWbÐDcÑDcÔDcÑ;cÔ;cÑ"c�à!Ø Ø#ð)˜ið )ð )Ø&ð)ð )ðð ð ð Ð.Ð.Ñ.ð	 Ý/°
Ñ;Ô;ˆNˆNøÝð 	 ð 	 ð 	 ØˆNˆNˆNð	 øøøàð $	àBÐB°>ÐBÑBÔBˆMØ#×)Ò)Ñ+Ô+¨}Ð<Ð<à $Ø#Ø"&Ø#ð	ð ð õ "& m×&8Ò&8Ñ&:Ô&:Ñ!;Ô!;ÐÝ$Ð%9×%?Ò%?Ñ%AÔ%AÐCUÐYZÐcfÐgÑgÔgˆDØð Ø)¨$¨q¬'Ô2�	à $Ø#Ø"&Ø'0ØP°)ÐPÐPÀIÐPÐPÐPðð ð õ ,Ð,@×,FÒ,FÑ,HÔ,HÐJ\Ð`aÐjmÐnÑnÔnˆKØ ˆOØð sØ"8¸4¿9º9ÐDrÐDrÐDrÐDrÐfqÐDrÑDrÔDrÑ;rÔ;rÑ"r�à ØØ#ðO˜ið Oð OØ&ðOð Oð Oð
ð 
ð 
ð$ �[Ò Ð Ý2Ñ4Ô4ÐØÐ'Ø#¥sÐ+;Ñ'<Ô'<Ð<Ð<à $Ø#Ø"&Ø#ð	ð ð õ %Ð%9Ð;KÈqÐY\Ð]Ñ]Ô]ˆDØð à $Ø#Ø"&Ø'+¨A¤wØN°)ÐNÐNÀDÈÄGÐNÐNÐNðð ð õ ,¨IÐ7GÈ1ÐUXÐYÑYÔYˆKØ ˆOØð dØ"8¸4¿9º9ÐDcÐDcÐWbÐDcÑDcÔDcÑ;cÔ;cÑ"c�ð
 !ØØ#ð)˜ið )ð )à&ð)ð )ð	ð 	ð 	ð Ð'Ò'Ð'Ý% g¨xÀ(ÐKÑKÔKˆ
ØÐ!Ø#¥s¨:¡¤Ð6Ð6à $Ø#Ø"&Ø#ð	ð ð õ %Ð%9¸:ÈÐSVÐWÑWÔWˆDØð à $Ø#Ø"&Ø'+¨A¤wØN°)ÐNÐNÀDÈÄGÐNÐNÐNðð ð ð ØØð)¨9ð )ð )ð )ð

ð 

ð 
	
õ " '¨8Ñ4Ô4€JàÐð ˜Ò!Ð!ðð à#ðñ ô ˆJð  ¥3 z¡?¤?Ð2Ð2ð !ØØ"Øð	ð ð õ %Ð%9¸:ÈÐSVÐWÑWÔWˆDØð à $Ø#Ø"&Ø'+¨A¤wØN°)ÐNÐNÀDÈÄGÐNÐNÐNðð ð õ ,¨I°zÀQÈsÐSÑSÔSˆKØ ˆOØð dØ"8¸4¿9º9ÐDcÐDcÐWbÐDcÑDcÔDcÑ;cÔ;cÑ"c�ð ØØð%˜)ð %ð %Ø"ð%ð %ð
ð 
ð 	
ð  �YÒÐð	Ø]Ð]Ð]Ð]Ð]Ð]Ð]Ð]Ø+Ð+Ñ-Ô-ˆFØ0Ð0°Ñ8Ô8ˆJØ:Ð:¨zÐ:Ñ:Ô:ˆNØ˜NÐ*Ð*à $Ø#Ø"&Ø#ð	ð ð õ ,¨Iµt¸NÑ7KÔ7KÈqÐY\Ð]Ñ]Ô]ˆKØ ˆOØð dØ"8¸4¿9º9ÐDcÐDcÐWbÐDcÑDcÔDcÑ;cÔ;cÑ"c�à ØØ#ð)˜ið )ð )ÐX^ð )ð )à&ð)ð )ð	ð 	ð 	øõ ð 	ð 	ð 	ØˆDð	øøøõ &×)Ò)¨*°jÑAÔA€NðÝ+¨JÑ7Ô7ˆˆøÝð ð ð Øˆˆˆðøøøð ð '
Ø>Ð>¨~Ð>Ñ>Ô>ˆØ×%Ò%Ñ'Ô'¨=Ð8Ð8à ØØ"Øð	ð ð õ " -×"4Ò"4Ñ"6Ô"6Ñ7Ô7ÐÝ Ø ×&Ò&Ñ(Ô(Ð*<ÀÈ#ð
ñ 
ô 
ˆð ð 	Ø% d¨1¤gÔ.ˆIà ØØ"Ø#,ØL¨iÐLÐLÀ	ÐLÐLÐLðð ð õ (Ø ×&Ò&Ñ(Ô(Ð*<ÀÈ#ð
ñ 
ô 
ˆð ˆØð 	Ø4°t·y²yð Að Að Að AØ1<ðAñ Aô Añ 8ô 8ñ ˆOð ØØðN˜)ð Nð N¸Nð Nð NØ<KðNð Nð Nð	
ð 	
ð 		
ð ØØðG¨ð Gð GÈ9ð Gð Gð Gðð ð sO   ÈH ÈH ÈH Ê9K	 Ë	KËKÖ3X ×AX Ø
X'Ø&X'ÙY ÙY%Ù$Y%)r=   r>   )r�   r‘   r’   r“   r=   r”   rò  )rŸ   r‘   r    r‘   r=   r¡   )r½   r¡   r=   r”   )rÆ   r>   r’   r“   rÇ   r”   r=   rÈ   )r=   r”   )r   rã   )r    r‘   r­   rš   rå   r”   r=   r¡   )r=   r‘   )rñ   r   r=   rò   )
r÷   r”   rÇ   rø   r    r‘   rå   r”   r=   rò   )r4  r‘   r=   r‘   )r’   r   r=   r”   )r>  r   r=   r”   )rD  )r­   rš   rå   r”   r=   r7   )rå   r”   r=   r>   )rs  r‘   r=   r‘   )r   rz  )
r6  r7   r{  r“   r|  r‘   r}  r‘   r=   r>   )Nr¦  rD  )
r§  r¨  r©  r‘   r­   rš   rå   r”   r=   r“   )r­   rš   rå   r”   r=   r“   )r=   r¸  )r4  r‘   rå   r”   r=   r“   )r=   rÆ  )rÝ  r‘   rÞ  r‘   r=   r¸  )r4  rò   rå   r”   r=   r7   )r4  r‘   r=   rÄ  )rþ  r‘   rÿ  rÄ  r=   r”   )rþ  r‘   r  rÄ  r=   r  )rõ   r‘   rÞ  r‘   r=   r  )rõ   r‘   r=   rò   )r4  rò   r=   r‘   )r�   r‘   r=   r‘   )r�   rò   r=   r”   )r�   rò   r=   r4  )r4  r‘   rP  r>   r=   r>   )r4  rò   rå   r”   r=   r>   )rã   )r­   rš   r=   r`  )ré   r   r=   r{  )r=   r‚  )r>  r¡   r=   r”   )Nrã   )r§  rò   r­   rš   r=   rœ  r  )r�   r‘   r§  rò   r=   r¤  )r©  rò   r=   r”   )r§  rò   r­   rš   r=   r`  )NN)rª  rœ  r§  rò   r=   rÄ  )r�   rò   rª  rœ  r§  rò   r=   r‘   )r�   r‘   r=   r>   )r�   r‘   r=   r”   )rÙ  rò   r�   rò   r=   r‘   )r�   rò   rª  rœ  r§  rò   r=   r>   )rã   N)
r§  rò   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=   r  )r§  rò   r©  rò   rå   r”   r=   r>   )rõ   r‘   r4  rò   r§  rò   r©  rò   rð  rò   r=   r¡   )|Ú__doc__Ú
__future__r   r³   rµ  Úurllib.requestr¯   Úurllib.errorr×   Údifflibr   Úpathlibr   Útypingr   r   r   Ú
hermes_clir	   Ú_HERMES_VERSIONr®  r¯  rž  r‰  rÆ  rÅ  r8   r  r9   r;   r<   rF   r‡   rž   r¼   rÅ   rÍ   rÐ   rÑ   rà   rç   rá   râ   rë   rð   rö   r  r  r  rÑ  rÏ  r7  r<  rC  rU  rÆ   r\  r`  rn  rq  rr  ry  r¥  r°  r²  r·  r»  rÃ  rJ  rA  rÅ  rÜ  ré  rÒ  rø  rý  r  Ú	frozensetr
  r  r  r  r  r¿  r&  r+  r,  r.  r1  r3  r:  r>  rE  rO  rö  r[  r�  rŠ  r›  r¡  r¢  r£  r©  r­  r°  rY  r½  rº  rÁ  rÇ  rÍ  rØ  rÜ  rÞ  rï  rü  r\  rZ  r  r  r  r  r]  rQ  r‰   rG   rE   ú<module>r\     sç  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø Ð Ð Ð Ø Ð Ð Ð Ø €€€Ø %Ð %Ð %Ð %Ð %Ð %Ø Ð Ð Ð Ð Ð Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,à 5Ð 5Ð 5Ð 5Ð 5Ð 5ð 5 ?Ð4Ð4Ð à2Ð Ø(Ð1Ð1Ð1Ð Ø)Ð Ø!EÐ!EÐ!EÐ Ø%>Ð%>Ð%>Ð "ð
",ð ",ð ",Ð ð "ð "ð "ñ "ðH ;?Ð Ð >Ð >Ð >Ñ >ð3ð 3ð 3Ð ð ð ð ñ ð$ ;?Ð Ð >Ð >Ð >Ñ >ñBð Bð Bð BðT*Ø
ð ð ð ðT*ðD ð 	ð 	ð 	ðET*ðX Ð)Ð)Ñ+Ô+ðYT*ðZ Øðð[T*ð` ð ð ð ðaT*ðF ð ð ð ðGT*ðR ð ð ð ðST*ð\ 
ð ð ð ð]T*ðn 
ØØ!ððoT*ðv ð ð ð ðwT*ðR ð ð ð ðST*ðd ð ð ð ðeT*ðr ØØððsT*ðz ð ð ð ð{T*ðH ð ð ð ðIT*ðT ð ð ð ðUT*ð` ð 	ð 	ð 	ðaT*ðtð ð ðð ð ðð ð ð
$ð $ð $ðJð ð ðð ð ð	ð 	ð 	ð
ð 
ð 
ðð ð ð ðgT*ð T*ð T*Ð ð Tð Tð Tñ Tðt "NÐ!MÐ4LÐ!MÑ!MÔ!MÐ �Ñ ñð ð ð ññ ð ð ð ñDð ð ð ñ$%ð %ð %ð %ð@  Ð Ð Ð Ð Ñ Ø.2Ð Ð 2Ð 2Ð 2Ñ 2ñ&ð &ð &ð &ðz  >Ð Ø#&Ð Ð &Ð &Ð &Ñ &àCEÐ Ð EÐ EÐ EÑ Eð Øñ'ð  ð	'ð 'ñ 'ð 'ð 'ð 'ñT1ð 1ð 1ð 1ñ ð ð ð ð Ø $ØØð6ð 6ñ 6ð 6ð 6ð 6ðHð ð ð ð �Jñ ô ð ð €M�& MÐ@jÑkÔkØ€M�, LÐ@gÑhÔhØ€M�,Ð$7Ð@|Ñ}Ô}Ø€M�+ KÐ@vÑwÔwØ€M�. NÀÑOÔOØ€M�( MÐ@|Ñ}Ô}Ø€M�( Lð  AAñ  Bô  BØ€M�,Ð$9Ð@jÑkÔkØ€M�)Ð$4Ð@uÑvÔvØ€M�-Ð$8Ð@uÑvÔvØ€M�- NÐ@tÑuÔuØ€M�(Ð$6Ð@xÑyÔyØ€MÐ%Ð'>ð  CSñ  Tô  TØ€M�* JÐ@rÑsÔsØ€M�% EÐ@bÑcÔcØ€M�% LÐ@bÑcÔcØ€M�-Ð$=Ð@pÑqÔqØ€MÐ"Ð$=Ð@pÑqÔqØ€M�)Ð$7Ð?zÑ{Ô{Ø€M�) IÐ@]Ñ^Ô^Ø€M�,Ð$5Ð@eÑfÔfØ€M�)Ð$?Ð@zÑ{Ô{Ø€M�. NÐ@xÑyÔyØ€M�' JÐ@jÑkÔkØ€M�* KÐ@^Ñ_Ô_Ø€M�. NÐ@rÑsÔsØ€M�- MÐ@sÑtÔtØ€M�) Mð  AAñ  Bô  BØ€M�/ Oð  AXñ  Yô  Yð;,Ð ð ð ð ñ ðB BÐAÐ-@ÐAÑAÔAÐ Ø.Ð �Ñ ð>Ø	ˆ5ð>à
ˆEð>ð ˆEð>ð ˆUð	>ð
 ˆið>ð �ið>ð �Yð>ð �Ið>ð ˜-ð>ð ˜ð>ð ˆhð>ð �Xð>ð ˜ð>ð ˆMð>ð �ð>ð  Ðð!>ð" Ð#ð#>ð >ð$ ˆIð%>ð& ˜9ð'>ð( �ð)>ð* ˆwð+>ð, �\ð->ð. �,ð/>ð0 ˆkð1>ð2 �;ð3>ð4 �ð5>ð6 �ð7>ð8 
ˆ>ð9>ð: 	ˆ-ð;>ð< �}ð=>ð> �ð?>ð@ ˆlðA>ðB ˜ðC>ðD ˆJðE>ð >ð >ðF �ðG>ðH �JðI>ðJ �ðK>ðL ˆiðM>ðN ˆIðO>ðP �YðQ>ðR �<ðS>ðT Ð%ðU>ðV Ð'ðW>ðX 	ˆ-ðY>ðZ �Mð[>ð\ �}ð]>ð^ ˆHð_>ð` �8ða>ðb 
ˆ9ðc>ðd �9ðe>ðf �iðg>ð >ðh ØØØØØØØØØ"ð{>ð >ð >Ð ñB'ð 'ð 'ð 'ñð ð ð ñð ð ð ð4 ñAð  ðAð Añ Að Að Að AðH (-ð Tð Tñ Tð Tð Tð Tñ
2ð 2ð 2ð 2ñ$ð ð ð ð ñEð  ðEð Eñ Eð Eð Eð EðP 38ð Tð Tñ Tð Tð Tð Tð 8:€Ð 9Ð 9Ñ 9Ñ 9ññ ð ð ð6 Øñ	;ñ ;ñ ;ð ;ð ;ð~ Ø/Øñ0ð
  ð0ð 0ñ 0ñ 0ð 0ð 0ðh ñ/ð  ð/ð /ñ /ñ /ð /ð /ñd7ñ 7ð 7ð 7ñ
	ñ 	ð 	ð 	ð FKð ð ñ ñ ð ð ð: €CÐ×ÒÑÔÑ Ô Ø	€cÐ
×
 Ò
 Ñ
"Ô
"Ñ#Ô#ñ$à�XÐñð ñ ð ñ ñ ñ)ñ )ð )ð )ñX!(ñ !(ð !(ð !(ñH
ñ 
ð 
ð 
ð   ð%ð %ñ %ñ %ð %ð %ñ2/ñ /ð /ð /ññ ð ð ð "˜	Ø?Ñ?Ð?ñô Ð ñ
-ñ -ð -ð -ñ`0ñ 0ð 0ð 0ñf$ñ $ð $ð $ñNñ ð ð ñ69ñ 9ð 9ð 9ñFñ Fð Fð Fð /8¨ið 9ñ 9ð 9ñ /ô /Ð ñ ð ñ ñ ð( /8¨iÙÙð9ñ /ô /Ð ñ ð ñ ñ ññ ð ð ñ/ñ /ð /ð /ñ/ñ /ð /ð /ñ(ñ (ð (ð (ñ$ñ ð ð ð2 )2¨	ð 3ñ 3ð 3ñ )ô )Ð ñ ð ñ ñ ñ&"ñ "ð "ð "ðJ JOð cð cñ cñ cð cð cñL)ñ )ñ )ð )ð )ñXñ ð ð ñ
ñ 
ð 
ð 
ñ$ñ ð ð ð< 58ñ ñ  ñ  ð  ð  ðL *,Ð Ñ +Ð +Ñ +Ñ +Ù%(Ð Ð (Ð (Ñ (Ñ (Ù!Ð ñ"ñ "ñ "ð "ð "ñJñ ð ð ñFñ Fñ Fð Fð Fð$Ù‘Lð$á™ð$ñ ™ð$ñ ™ð	$ñ
 ‘ið$ñ ™9ð$ñ ™9ð$ñ ‘Xð$ñ ™-ð$ñ ‘ð$ñ ‘lð$ñ ™ð$ñ ‘ð$ñ ‘lð$ñ ‘lð$ñ   Ñ!2ð!$ñ" "Ñ#6ð#$ñ$ "3Ù#6Ù"4ñ )Ù,Ù*Ù,Ù*Ù!2Ù#6Ù#4Ù#6Ù"4ñG$ð $ð $Ð ðP /3Ø!ññ ñ ð ð ð$ /3Ø!ñ	&ð &ñ &ñ &ð &ð &ñRñ ð ð ñ@ñ @ð @ð @ð( /3Ø!ñ	&ð &ñ &ñ &ð &ð &ñR
ñ 
ð 
ð 
ññ ð ð ðJ /3Ø!ñ	)Oð )Oñ )Oñ )Oð )Oð )Oð^ Ø"ñ	Kñ Kñ Kð Kð Kñ\ñ ñ ð ð ðB Ø"ñ	añ añ að að añ( Ð ñ@ñ @ð @ð @ð 49ñ ð ñ ñ ð ð ñ6ñ ð ð ð "Ø"ñ?ð  ð	?ð ?ñ ?ñ ?ð ?ð ?ðL "Ø"Ø"ñuð uñ uñ uð uð uð uð urG   