§
    øžyjÍ„  ã                  ó˜  — U d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	m
Z
mZ ddlmZmZ  ej        e¦  «        Z ed¬¦  «         G d	„ d
¦  «        ¦   «         Zi d eddd¬¦  «        “d eddd¬¦  «        “d eddd¬¦  «        “d eddd¬¦  «        “d eddd¬¦  «        “d edddd ¬!¦  «        “d" eddd#d$¬!¦  «        “d% edd&d'd(d)¬*¦  «        “d+ edd,d-d.¬!¦  «        “d/ edd0¬1¦  «        “d2 ed3d4¬1¦  «        “d5 edd6d7¬8¦  «        “d9 edd:¬;¦  «        “d< edd=d>d?¬@¦  «        “dA ed3dB¬;¦  «        “dC ed3ddD¬¦  «        “dE ed3dF¬;¦  «        “i dG eddH¬;¦  «        “dI eddJ¬;¦  «        “dK eddL¬;¦  «        “dM edd¬N¦  «        “dO edddP¬¦  «        “dQ edddR¬¦  «        “dS edddT¬¦  «        “dU edddV¬¦  «        “dW edddX¬¦  «        “dY eddd ¬¦  «        “dZ edd[d\¬¦  «        “d] edd^¬;¦  «        “d_ edd`¬;¦  «        “da eddbdc¬¦  «        “dd eddedfdg¬@¦  «        “dh eddidj¬k¦  «        “dl eddmdndo¬@¦  «        “¥ eddpdqdr¬@¦  «         eddsdt¬¦  «         eddu¬;¦  «         edvdw¬x¦  «         eddy¬x¦  «        dzœ¥Zd{ed|<   e G d}„ d~¦  «        ¦   «         Zi dd“d€d5“d�d5“d‚d5“dƒd5“d„dY“d…dY“d†dY“d‡d“dd“dˆd“d‰d“dŠdZ“d‹dZ“dŒdZ“d�dZ“dŽd9“i d�d9“d�d9“d‘d9“d’d<“d“d<“d”dE“d•dE“d–d2“d—d2“d˜d/“d™d/“dšd+“d›dM“dœdM“d�dM“dždO“dŸdO“¥i d dQ“d¡dQ“d¢dS“d£dS“d¤dS“d¥dG“d¦dI“d§dI“d¨dI“d©dI“dªdK“d«dK“d¬dK“d­dU“d®dU“d¯dU“d°dW“¥i d±dW“d²d]“d³d]“d´d_“dµd_“d¶d_“d·d_“d¸d¹“dºd¹“d»d¹“d¼d¹“d½da“d¾da“d¿dd“dÀdd“dÁdh“dÂdh“¥dÃdldldld%d%d%dÄdÅdÅdÅdÅdÆœ¥ZdÇedÈ<   i ddÉ“ddÊ“ddË“d+dÌ“d<dÍ“d]dÎ“dddÏ“dÃdÐ“dldÑ“d_dÒ“d%dÓ“dÅdÔ“d¹dÕ“dydÖ“d×dØ“ddÙ“ZdÇedÚ<   dÛd3ddvdÜœZdÇedÝ<   �ddá„Zddâœ�ddæ„Z�ddè„Z�ddê„Z edQdOh¦  «        Zdëedì<   �ddí„Z�ddï„Z �d�d	dò„Z!�d�d
dô„Z"�d�ddõ„Z#�ddø„Z$�d�ddû„Z%	 �d�ddü„Z&�ddÿ„Z'	 	 �d�d�d„Z(dS (  u‹  
Single source of truth for provider identity in Hermes Agent.

Two data sources, merged at runtime:

1. **models.dev catalog** â€” 109+ providers with base URLs, env vars, display
   names, and full model metadata (context, cost, capabilities).  This is
   the primary database.

2. **Hermes overlays** â€” transport type, auth patterns, aggregator flags,
   and additional env vars that models.dev doesn't track.  Small dict,
   maintained here.

3. **User config** (``providers:`` section in config.yaml) â€” user-defined
   endpoints and overrides.  Merged on top of everything else.

Other modules import from this file.  No parallel registries.
é    )ÚannotationsN)Ú	dataclass)ÚAnyÚDictÚListÚOptionalÚTuple)Úbase_url_host_matchesÚbase_url_hostnameT)Úfrozenc                  óh   — e Zd ZU dZdZded<   dZded<   dZded	<   d
Zded<   dZ	ded<   dZ
ded<   dS )ÚHermesOverlayz?Hermes-specific provider metadata layered on top of models.dev.Úopenai_chatÚstrÚ	transportFÚboolÚis_aggregatorÚapi_keyÚ	auth_type© úTuple[str, ...]Úextra_env_varsÚ Úbase_url_overrideÚbase_url_env_varN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__r   r   r   r   r   r   ó    ú:/home/ragecks/.hermes/hermes-agent/hermes_cli/providers.pyr   r   "   s€   € € € € € € àIÐIà"€IÐ"Ð"Ð"Ñ"Ø€MÐÐÐÑØ€IÐÐÐÑØ&(€NÐ(Ð(Ð(Ñ(ØÐÐÐÐÑØÐÐÐÐÑÐÐr!   r   Úmoar   Úvirtualzmoa://local)r   r   r   Ú
openrouterÚOPENROUTER_BASE_URL)r   r   r   ÚnousÚoauth_device_codez)https://inference-api.nousresearch.com/v1zopenai-codexÚcodex_responsesÚoauth_externalz%https://chatgpt.com/backend-api/codexz
openai-apizhttps://api.openai.com/v1ÚOPENAI_BASE_URL)r   r   r   z	xai-oauthzhttps://api.x.ai/v1ÚXAI_BASE_URL)r   r   r   r   z
qwen-oauthzhttps://portal.qwen.ai/v1ÚHERMES_QWEN_BASE_URLÚlmstudior   )Ú
LM_API_KEYzhttp://127.0.0.1:1234/v1ÚLM_BASE_URL)r   r   r   r   r   zcopilot-acpÚexternal_processzacp://copilotÚCOPILOT_ACP_BASE_URLzgithub-copilot)ÚCOPILOT_GITHUB_TOKENÚGH_TOKEN)r   r   Ú	anthropicÚanthropic_messages)ÚANTHROPIC_TOKENÚCLAUDE_CODE_OAUTH_TOKENÚzai)ÚGLM_API_KEYÚZAI_API_KEYÚZ_AI_API_KEYÚGLM_BASE_URL)r   r   r   zkimi-for-codingÚKIMI_BASE_URL)r   r   Ústepfun)ÚSTEPFUN_API_KEYz#https://api.stepfun.ai/step_plan/v1ÚSTEPFUN_BASE_URL)r   r   r   r   ÚminimaxÚMINIMAX_BASE_URLzminimax-oauthz https://api.minimax.io/anthropicz
minimax-cnÚMINIMAX_CN_BASE_URLÚdeepseekÚDEEPSEEK_BASE_URLÚalibabaÚDASHSCOPE_BASE_URLzalibaba-coding-planÚALIBABA_CODING_PLAN_BASE_URLÚvercel)r   r   ÚopencodeÚOPENCODE_ZEN_BASE_URLzopencode-goÚOPENCODE_GO_BASE_URLÚkiloÚKILOCODE_BASE_URLÚhuggingfaceÚHF_BASE_URLÚnovitaÚNOVITA_BASE_URLÚxaiÚnvidiaz#https://integrate.api.nvidia.com/v1ÚNVIDIA_BASE_URLÚxiaomiÚXIAOMI_BASE_URLztencent-tokenhubÚTOKENHUB_BASE_URLÚarceezhttps://api.arcee.ai/api/v1ÚARCEE_BASE_URLÚgmi)ÚGMI_API_KEYzhttps://api.gmi-serving.com/v1ÚGMI_BASE_URLÚ	fireworks)ÚFIREWORKS_API_KEYz%https://api.fireworks.ai/inference/v1)r   r   r   Úactual)ÚACTUAL_API_KEYÚACTUAL_BASE_URLzhttps://api.actual.inc/v1rc   )ÚUPSTAGE_API_KEYzhttps://api.upstage.ai/v1ÚUPSTAGE_BASE_URLzhttps://ollama.com/v1ÚOLLAMA_BASE_URLÚAZURE_FOUNDRY_BASE_URLÚbedrock_converseÚaws_sdk)r   r   Úvertex)Úupstageúollama-cloudzazure-foundryÚbedrockrj   zDict[str, HermesOverlay]ÚHERMES_OVERLAYSc                  ó�   — e Zd ZU dZded<   ded<   ded<   ded<   dZded	<   dZded
<   dZded<   dZded<   dZ	ded<   dZ
ded<   dS )ÚProviderDefu9   Complete provider definition â€” merged from all sources.r   ÚidÚnamer   r   Úapi_key_env_varsr   Úbase_urlr   Fr   r   r   r   ÚdocÚsourceN)r   r   r   r   r    rt   r   r   r   ru   rv   r   r!   r"   rp   rp   þ   s¢   € € € € € € àCÐCà€G€G�GØ€I€I�IØ€N€N�NØ%Ð%Ð%Ñ%Ø€HÐÐÐÑØÐÐÐÐÑØ€MÐÐÐÑØ€IÐÐÐÑØ€C€M€M€M�MØ€FÐÐÐÑÐÐr!   rp   ÚopenaiÚglmzz-aizz.aiÚzhipuzx-aizx.aiÚgrokz
grok-oauthz
x-ai-oauthzxai-grok-oauthÚnimz
nvidia-nimzbuild-nvidiaÚnemotronÚkimizkimi-codingzkimi-coding-cnÚmoonshotÚstepzstepfun-coding-planzminimax-chinaÚ
minimax_cnÚclaudezclaude-codeÚcopilotÚgithubzgithub-copilot-acpz
ai-gatewayÚ	aigatewayzvercel-ai-gatewayzopencode-zenÚzenÚgozopencode-go-subÚkilocodez	kilo-codezkilo-gatewayz	deep-seekÚ	dashscopeÚaliyunÚqwenzalibaba-cloudÚalibaba_codingzalibaba-codingÚalibaba_coding_planÚhfzhugging-facezhuggingface-hubz	novita-aiÚnovitaaiÚmimozxiaomi-mimoÚtencentÚtokenhubztencent-cloudÚtencentmaasÚawsrm   zaws-bedrockzamazon-bedrockÚamazonzarcee-aiÚarceeaiz	gmi-cloudÚgmicloudzfireworks-aiÚfwrk   ÚcustomÚlocal)Úsolarzactual-computerÚactualcomputerÚacir.   z	lm-studioÚ	lm_studioÚollamaÚvllmÚllamacppz	llama.cppz	llama-cppzDict[str, str]ÚALIASESzMixture of AgentszNous PortalzOpenAI CodexzGitHub Copilot ACPzStepFun Step PlanzXiaomi MiMoz	GMI CloudzUpstage SolarzActual ComputerzTencent TokenHubz	LM StudiozLocal endpointzAWS BedrockzGoogle Vertex AIrl   zOllama Cloudz%xAI Grok OAuth (SuperGrok / Premium+)Ú_LABEL_OVERRIDESÚchat_completions)r   r6   r)   rh   ÚTRANSPORT_TO_API_MODErr   r   Úreturnc                ó„   — |                       ¦   «                              ¦   «         }t                               ||¦  «        S )z±Resolve aliases and normalise casing to a canonical provider id.

    Returns the canonical id string.  Does *not* validate that the id
    corresponds to a known provider.
    )ÚstripÚlowerr¡   Úget)rr   Úkeys     r"   Únormalize_providerr«   ½  s1   € ð �*Š*‰,Œ,×
Ò
Ñ
Ô
€CÝ�;Š;�s˜CÑ Ô Ð r!   ©Úallow_networkr­   r   úOptional[ProviderDef]c               óÂ  — t          | ¦  «        }	 ddlm} |r ||¦  «        n ||d¬¦  «        }n# t          $ r d}Y nw xY wt                               |¦  «        }|�®|r|j        nd}|r|j        nd}|r|j        nd}|r|j	        nd}	|r|j
        nd}
t          |j        ¦  «        }|r*|j        r#|j        D ]}||vr|                     |¦  «         Œt          ||j        |t#          |¦  «        |
p|j        |	|||j        d	¬
¦
  «
        S |�Ot          |t(                               ||¦  «        |j        |j        |j
        |j	        |j        |j        d¬¦	  «	        S dS )aA  Look up a built-in provider by id or alias.

    Resolution order:
      1. Hermes overlays (for providers not in models.dev: nous, openai-codex, etc.)
      2. models.dev catalog + Hermes overlay

    User-defined providers from config.yaml (``providers:`` / ``custom_providers:``)
    are resolved by :func:`resolve_provider_full`, which layers ``resolve_user_provider``
    and ``resolve_custom_provider`` on top of this function. Callers that need
    user-config support should use ``resolve_provider_full`` instead.

    Returns a fully-resolved ProviderDef or None.
    r   ©Úget_provider_infoFr¬   Nr   r   r   ú
models.dev)
rq   rr   r   rs   rt   r   r   r   ru   rv   Úhermes)	rq   rr   r   rs   rt   r   r   r   rv   )r«   Úagent.models_devr±   Ú	Exceptionrn   r©   r   r   r   r   r   ÚlistÚenvr   Úappendrp   rr   ÚtupleÚapiru   r¢   )rr   r­   Ú	canonicalÚ_mdev_providerÚ	mdev_infoÚoverlayr   Úis_aggÚauthÚbase_url_envr   Úenv_varsÚevs                r"   Úget_providerrÄ   Ç  só  € õ # 4Ñ(Ô(€Ið
ØHÐHÐHÐHÐHÐHð
 ð@ˆNˆN˜9Ñ%Ô%Ð%à� 	¸Ð?Ñ?Ô?ð 	ˆ	øõ
 ð ð ð Øˆ	ˆ	ˆ	ðøøøõ ×!Ò! )Ñ,Ô,€GàÐà)0ÐC�GÔ%Ð%°mˆ	Ø*1Ð<�Ô&Ð&°uˆØ$+Ð:ˆwÔ Ð °ˆØ3:ÐB�wÔ/Ð/ÀˆØ9@ÐH˜GÔ5Ð5ÀbÐõ ˜	œÑ&Ô&ˆØð 	(�wÔ-ð 	(ØÔ,ð (ð (�Ø˜XÐ%Ð%Ø—O’O BÑ'Ô'Ð'øåØØ”ØÝ" 8™_œ_Ø&Ð7¨)¬-Ø)Ø ØØ”Øð
ñ 
ô 
ð 	
ð ÐåØÝ!×%Ò% i°Ñ;Ô;ØÔ'Ø$Ô3ØÔ.Ø$Ô5Ø!Ô/ØÔ'Øð

ñ 

ô 

ð 
	
ð ˆ4s   ‘ 2 ²AÁ AÚprovider_idc                ó€   — t          | ¦  «        }|t          v rt          |         S t          |¦  «        }|r|j        S |S )z1Get a human-readable display name for a provider.)r«   r¢   rÄ   rr   )rÅ   r»   Úpdefs      r"   Ú	get_labelrÈ     sM   € å" ;Ñ/Ô/€Ið Õ$Ð$Ð$Ý 	Ô*Ð*õ ˜	Ñ"Ô"€DØð ØŒyÐàÐr!   Úproviderc                ó†   — t          | pd¦  «        }|                     d¦  «        rdS t          |¦  «        }|r|j        ndS )z:Return True when the provider is a multi-model aggregator.r   úcustom:TF)r«   Ú
startswithrÄ   r   )rÉ   Úprovider_normrÇ   s      r"   r   r   %  sN   € å& x ~°2Ñ6Ô6€MØ×Ò 	Ñ*Ô*ð ØˆtÝ˜Ñ&Ô&€DØ!%Ð0ˆ4ÔÐ¨5Ð0r!   úfrozenset[str]Ú_FLAT_NAMESPACE_RESELLERSc                óX   — t          | pd¦  «        }|t          v rdS t          |¦  «        S )ux  Return True only for TRUE routing aggregators (e.g. OpenRouter, named
    ``custom:*`` proxies) â€” those that route bare/vendor-slugged model names
    to *other* providers' endpoints.

    Distinct from :func:`is_aggregator`, which also reports True for
    flat-namespace resellers (opencode-go/zen) whose catalog is entirely
    first-party. Use this gate when the question is "would selecting this
    model silently re-route the call away from the user's intended provider?"
    â€” i.e. the picker dedup. Resellers answer no: their listed models are
    their own, so their rows must not be deduped against user proxies.
    r   F)r«   rÏ   r   )rÉ   rÍ   s     r"   Úis_routing_aggregatorrÑ   ?  s4   € õ ' x ~°2Ñ6Ô6€MØÕ1Ð1Ð1ØˆuÝ˜Ñ'Ô'Ð'r!   rt   c                ó"   — t          | d¦  «        S )u¿  True when *base_url* points at OpenAI's official API host family.

    Matches the canonical host (``api.openai.com``) and OpenAI's documented
    data-residency / regional hosts (``us.api.openai.com``,
    ``eu.api.openai.com``, and any future ``<region>.api.openai.com``) â€”
    those serve the same API surface with the same transport requirements
    and the same access-scoped ``/v1/models`` listing.

    Hostname-parsed matching only â€” never substring â€” so lookalike hosts
    (``api.openai.com.attacker.test``) and path-segment spoofs
    (``proxy.test/api.openai.com/v1``) are rejected. A genuine
    ``*.api.openai.com`` subdomain requires control of openai.com DNS, so
    the dot-suffix match does not reopen the #32243 spoofing hole.
    Delegates to ``utils.base_url_host_matches``, which owns the
    exact-or-dot-suffix hostname contract (userinfo/port stripped,
    lowercased, trailing dot removed) â€” one implementation, not two.
    zapi.openai.com)r
   )rt   s    r"   Úis_official_openai_hostrÓ   Q  s   € õ$ ! Ð+;Ñ<Ô<Ð<r!   r   úOptional[str]c                ó<  — | sdS |                       d¦  «                             ¦   «         }t          | ¦  «        }|dk    rd|v rdS |dk    s|                     d¦  «        rdS t	          | ¦  «        rdS |                     d	¦  «        rt          | d
¦  «        rdS dS )u;  Return the wire protocol a specific endpoint *requires*, or None.

    Some hosts only accept one API mode and reject the others outright:
      - api.openai.com only accepts the Responses API for its (reasoning)
        models when tools + reasoning are in play (chat/completions 400s).
      - api.anthropic.com / ``â€¦/anthropic`` suffixes speak native Messages.
      - Kimi's ``/coding`` endpoint speaks native Messages.
      - AWS Bedrock runtime hosts speak Converse.

    These are *mandatory* â€” a session carrying a stale api_mode (e.g. a
    /model switch that kept the previous provider's ``chat_completions``)
    must be overridden to the host's required mode, not merely filled in
    when empty. Generic / unknown endpoints return None so an explicitly
    configured api_mode on them is never clobbered.
    Nú/zapi.kimi.comz/codingr6   zapi.anthropic.comz
/anthropicr)   zbedrock-runtime.zamazonaws.comrh   )Úrstripr¨   r   ÚendswithrÓ   rÌ   r
   )rt   Ú	url_lowerÚhostnames      r"   Úhost_mandated_api_moderÛ   f  sÊ   € ð  ð ØˆtØ—’ Ñ$Ô$×*Ò*Ñ,Ô,€IÝ  Ñ*Ô*€Hð �>Ò!Ð! i°9Ð&<Ð&<Ø#Ð#ØÐ&Ò&Ð&¨)×*<Ò*<¸\Ñ*JÔ*JÐ&Ø#Ð#õ
 ˜xÑ(Ô(ð !Ø Ð Ø×ÒÐ-Ñ.Ô.ð "Õ3HÈÐSbÑ3cÔ3cð "Ø!Ð!Øˆ4r!   Úmodelc                óš   — t          | pd¦  «                             ¦   «                              ¦   «                              d¦  «        rdS dS )uŽ  Resolve the wire protocol for a Nous Portal model.

    Portal serves its ``anthropic/*`` catalog on a native Anthropic Messages
    route (``/v1/messages``) alongside the OpenAI-compatible
    ``/v1/chat/completions`` used by every other model it proxies.  Claude
    traffic goes to the native route so it gets Anthropic's own request shape
    (inner-block ``cache_control`` breakpoints, thinking blocks) instead of the
    OpenAI-wire translation.

    When *model* is empty/unknown, defaults to ``chat_completions`` â€” the
    historical Nous transport â€” so callers that don't yet know the model
    stay on the safer OpenAI-compatible path.
    r   z
anthropic/r6   r£   )r   r§   r¨   rÌ   )rÜ   s    r"   Únous_api_moderÞ   Œ  sJ   € õ ˆ5ˆ;�BÑÔ×ÒÑÔ×%Ò%Ñ'Ô'×2Ò2°<Ñ@Ô@ð $Ø#Ð#ØÐr!   c                ó  — t          |¦  «        }|�|S | pd                     ¦   «                              ¦   «         }|dv rt          |¦  «        S t	          | ¦  «        }|� t
                               |j        d¦  «        S | dk    rdS dS )u  Determine the API mode (wire protocol) for a provider/endpoint.

    Resolution order:
      1. Host-mandated mode (special endpoints that only accept one protocol).
      2. Nous Portal dual-wire (model-derived; overlay alone is openai_chat).
      3. Known provider â†’ transport â†’ TRANSPORT_TO_API_MODE.
      4. Direct provider checks (bedrock).
      5. Default: 'chat_completions'.

    *model* is optional but required for dual-wire providers (Nous) whose
    transport depends on the catalog id, not just the provider/host.
    Nr   >   únous-portalr'   Únousresearchr£   rm   rh   )rÛ   r§   r¨   rÞ   rÄ   r¤   r©   r   )rÉ   rt   rÜ   ÚmandatedrÍ   rÇ   s         r"   Údetermine_api_moderã   Ÿ  sž   € õ & hÑ/Ô/€HØÐØˆð �^ ×*Ò*Ñ,Ô,×2Ò2Ñ4Ô4€MØÐ?Ð?Ð?Ý˜UÑ#Ô#Ð#å˜Ñ!Ô!€DØÐÝ$×(Ò(¨¬Ð9KÑLÔLÐLð �9ÒÐØ!Ð!àÐr!   Úuser_configúDict[str, Any]c           
     ó  — |rt          |t          ¦  «        sdS |                     | ¦  «        }t          |t          ¦  «        sdS |                     dd¦  «        p| }|                     dd¦  «        p-|                     dd¦  «        p|                     dd¦  «        pd}|                     dd¦  «        pd}|                     dd	¦  «        pd	}g }|r|                     |¦  «         t	          | ||t          |¦  «        |d
dd¬¦  «        S )zþResolve a provider from the user's config.yaml ``providers:`` section.

    Args:
        name: Provider name as given by the user.
        user_config: The ``providers:`` dict from config.yaml.

    Returns:
        ProviderDef if found, else None.
    Nrr   r   rº   Úurlrt   Úkey_envr   r   Fr   úuser-config©rq   rr   r   rs   rt   r   r   rv   )Ú
isinstanceÚdictr©   r¸   rp   r¹   )rr   rä   ÚentryÚdisplay_nameÚapi_urlrè   r   rÂ   s           r"   Úresolve_user_providerrð   Å  s(  € ð ð �j¨µdÑ;Ô;ð Øˆtà�OŠO˜DÑ!Ô!€EÝ�e�TÑ"Ô"ð Øˆtð —9’9˜V RÑ(Ô(Ð0¨D€LØ�iŠi˜˜rÑ"Ô"Ð] e§i¢i°°rÑ&:Ô&:Ð]¸e¿iºiÈ
ÐTVÑ>WÔ>WÐ]Ð[]€GØ�iŠi˜	 2Ñ&Ô&Ð,¨"€GØ—	’	˜+ }Ñ5Ô5ÐF¸€Ià€HØð !Ø�Š˜Ñ Ô Ð åØØØÝ˜x™œØØØØð	ñ 	ô 	ð 	r!   rî   Úprovider_keyc                ó  — t          |pd¦  «                             ¦   «         p"t          | pd¦  «                             ¦   «         }|                     ¦   «                              dd¦  «        }|                     d¦  «        r|nd|› �S )a0  Build the stable ``custom:`` identity for a configured provider.

    Keyed ``providers:`` entries keep their config key as the durable
    identity even when their display name changes. Legacy
    ``custom_providers:`` entries have no key, so their normalized display
    name remains the identity.
    r   ú ú-rË   )r   r§   r¨   ÚreplacerÌ   )rî   rñ   ÚidentityÚ
normalizeds       r"   Úcustom_provider_slugrø   ì  s…   € õ �<Ð% 2Ñ&Ô&×,Ò,Ñ.Ô.ÐQµ#°lÐ6HÀbÑ2IÔ2I×2OÒ2OÑ2QÔ2Q€HØ—’Ñ!Ô!×)Ò)¨#¨sÑ3Ô3€JØ#×.Ò.¨yÑ9Ô9ÐUˆ:ˆ:Ð?UÈÐ?UÐ?UÐUr!   c                óÊ  — t          ¦   «         }| |fD ]Â}t          |pd¦  «                             ¦   «                              ¦   «         }|sŒ:|                     dd¦  «        }|                     ||t          |¦  «        h¦  «         |                     d¦  «        r8|                     dd¦  «        d         }|r|                     |d|› �h¦  «         ŒÃt          |¦  «        S )zCReturn every current and legacy identity accepted for one endpoint.r   ró   rô   rË   ú:é   )
Úsetr   r§   r¨   rõ   Úupdaterø   rÌ   ÚsplitÚ	frozenset)rî   rñ   ÚaliasesÚvalueÚrawr÷   Úsuffixs          r"   Úcustom_provider_aliasesr  ù  sõ   € õ
 ™œ€GØ Ð-ð 	Að 	AˆÝ�%�+˜2ÑÔ×$Ò$Ñ&Ô&×,Ò,Ñ.Ô.ˆØð 	ØØ—[’[  cÑ*Ô*ˆ
Ø�Š˜˜ZÕ)=¸jÑ)IÔ)IÐJÑKÔKÐKØ× Ò  Ñ+Ô+ð 	AØ×%Ò% c¨1Ñ-Ô-¨aÔ0ˆFØð AØ—’ Ð(>°*Ð(>Ð(>Ð?Ñ@Ô@Ð@øÝ�WÑÔÐr!   Úcustom_providersúOptional[List[Dict[str, Any]]]c                óÒ  — |rt          |t          ¦  «        sdS | pd                     ¦   «                              ¦   «         }|sdS |dk    }d}|D �]s}t          |t          ¦  «        sŒ|                     d¦  «        pd                     ¦   «         }|                     dd¦  «        p-|                     dd¦  «        p|                     dd¦  «        pd                     ¦   «         }|r|sŒ�|                     d¦  «        pd                     ¦   «         }|                     d	¦  «        pd                     ¦   «         }	g }
|r|
                     |¦  «         |€!||t          |
¦  «        t          ||	¦  «        f}t          ||	¦  «        }|t          ||	¦  «        vr�ŒOt          ||d
t          |
¦  «        |ddd¬¦  «        c S |r |r|\  }}}}t          ||d
||ddd¬¦  «        S dS )zIResolve a provider from the user's config.yaml ``custom_providers`` list.Nr   r˜   rr   rt   rç   rº   rè   rñ   r   Fr   ré   rê   )rë   r¶   r§   r¨   rì   r©   r¸   r¹   rø   r  rp   )rr   r  Ú	requestedÚbare_custom_fallbackÚfirst_validrí   rî   rï   rè   rñ   rÂ   ÚslugÚdnameÚaurlÚdenvs                  r"   Úresolve_custom_providerr    s^  € ð
 ð ¥:Ð.>ÅÑ#EÔ#Eð Øˆtà�˜×"Ò"Ñ$Ô$×*Ò*Ñ,Ô,€IØð Øˆtð
 %¨Ò0ÐØCG€Kà!ð *
ñ *
ˆÝ˜%¥Ñ&Ô&ð 	ØàŸ	š	 &Ñ)Ô)Ð/¨R×6Ò6Ñ8Ô8ˆà�IŠI�j "Ñ%Ô%ð Ø�yŠy˜ Ñ#Ô#ðà�yŠy˜ Ñ#Ô#ðð ß
Š%‰'Œ'ð 	ð ð 	 7ð 	Øà—9’9˜YÑ'Ô'Ð-¨2×4Ò4Ñ6Ô6ˆØŸ	š	 .Ñ1Ô1Ð7°R×>Ò>Ñ@Ô@ˆØ ˆØð 	%Ø�OŠO˜GÑ$Ô$Ð$ð ÐàØÝ�h‘”Ý$ \°<Ñ@Ô@ð	ˆKõ $ L°,Ñ?Ô?ˆØÕ3°LÀ,ÑOÔOÐOÐOÙåØØØ#Ý" 8™_œ_ØØØØ ð	
ñ 	
ô 	
ð 		
ð 		
ð 		
ð ð 
 ð 
Ø"-Ñˆˆt�T˜4ÝØØØ#Ø!ØØØØ ð	
ñ 	
ô 	
ð 		
ð ˆ4r!   Úuser_providersúOptional[Dict[str, Any]]c                óò  ‡— t          | ¦  «        Š|                      ¦   «                              ¦   «         }|rt          ||¦  «        }|�|S ‰|k    rŠ	 ddlm} |                     |¦  «        }|�[ˆfd„|D ¦   «         }t          |¦  «        dk    r:t          |j	        |j
        dt          |j        pd¦  «        |j        pdd	¬
¦  «        S n# t          $ r Y nw xY wt          ‰¦  «        }|�|S |r(t          ‰|¦  «        }|�|S t          ||¦  «        }|�|S t!          | |¦  «        }	|	�|	S 	 ddlm}
  |
‰¦  «        }|�$t          ‰|j
        d|j        |j        d¬
¦  «        S n# t          $ r Y nw xY wdS )u‘  Full resolution chain: built-in â†’ models.dev â†’ user config.

    This is the main entry point for --provider flag resolution.

    Args:
        name: Provider name or alias.
        user_providers: The ``providers:`` dict from config.yaml (optional).
        custom_providers: The ``custom_providers:`` list from config.yaml (optional).

    Returns:
        ProviderDef if found, else None.
    Nr   )ÚPROVIDER_REGISTRYc                ó:   •— g | ]}t          |¦  «        ‰k    ¯|‘ŒS r   )r«   )Ú.0Ú_ridr»   s     €r"   ú
<listcomp>z)resolve_provider_full.<locals>.<listcomp>‰  s6   ø€ ð 'ð 'ð 'àÝ)¨$Ñ/Ô/°9Ò<Ð<ð à<Ð<Ð<r!   rû   r   r   r   zhermes-auth-registry)rq   rr   r   rs   rt   rv   r°   r²   )r«   r§   r¨   rð   Úhermes_cli.authr  r©   Úlenrp   rq   rr   r¹   rs   Úinference_base_urlrµ   rÄ   r  r´   r±   r·   rº   )rr   r  r  r  Ú	user_pdefÚ_AUTH_PROVIDER_REGISTRYÚ_pcfgÚ_collapsed_siblingsrÇ   Úcustom_pdefr¼   r½   r»   s               @r"   Úresolve_provider_fullr   [  s5  ø€ õ" # 4Ñ(Ô(€IØ
�*Š*‰,Œ,×
Ò
Ñ
Ô
€Cð ð Ý)¨#¨~Ñ>Ô>ˆ	ØÐ ØÐð �CÒÐð	ØTÐTÐTÐTÐTÐTØ+×/Ò/°Ñ4Ô4ˆEØÐ ð'ð 'ð 'ð 'à 7ð'ñ 'ô 'Ð#õ
 Ð*Ñ+Ô+¨aÒ/Ð/Ý&Ø œ8Ø"œZØ"/Ý).¨uÔ/EÐ/KÈÑ)LÔ)LØ!&Ô!9Ð!?¸RØ5ðñ ô ð øøõ ð 	ð 	ð 	ØˆDð	øøøõ ˜	Ñ"Ô"€DØÐØˆð ð å)¨)°^ÑDÔDˆ	ØÐ ØÐå)¨#¨~Ñ>Ô>ˆ	ØÐ ØÐõ *¨$Ð0@ÑAÔA€KØÐØÐðØHÐHÐHÐHÐHÐHØ"�N 9Ñ-Ô-ˆ	ØÐ ÝØØ”^Ø'Ø!*¤Ø"œØ#ðñ ô ð ð !øõ ð ð ð Øˆðøøøð ˆ4s%   ÁA7C Ã
CÃCÄ/6E' Å'
E4Å3E4)rr   r   r¥   r   )rr   r   r­   r   r¥   r®   )rÅ   r   r¥   r   )rÉ   r   r¥   r   )rt   r   r¥   r   )r   )rt   r   r¥   rÔ   )rÜ   r   r¥   r   )r   r   )rÉ   r   rt   r   rÜ   r   r¥   r   )rr   r   rä   rå   r¥   r®   )rî   r   rñ   r   r¥   r   )rî   r   rñ   r   r¥   rÎ   )rr   r   r  r  r¥   r®   )NN)rr   r   r  r  r  r  r¥   r®   ))r   Ú
__future__r   ÚloggingÚdataclassesr   Útypingr   r   r   r   r	   Úutilsr
   r   Ú	getLoggerr   Úloggerr   rn   r    rp   r¡   r¢   r¤   r«   rÄ   rÈ   r   rÿ   rÏ   rÑ   rÓ   rÛ   rÞ   rã   rð   rø   r  r  r   r   r!   r"   ú<module>r(     sY  ððð ð ð& #Ð "Ð "Ð "Ð "Ð "à €€€Ø !Ð !Ð !Ð !Ð !Ð !Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3à :Ð :Ð :Ð :Ð :Ð :Ð :Ð :à	ˆÔ	˜8Ñ	$Ô	$€ð €�$ÐÑÔðð ð ð ð ñ ô ñ ÔððJ-Ø	ˆ=ˆ=ØØØ'ðñ ô ðJ-ð �-�-ØØØ.ðñ ô ðJ-ð ˆMˆMØØ%ØEðñ ô ðJ-ð  �M�MØ#Ø"ØAðñ ô ð!J-ð* �-�-Ø#Ø5Ø*ðñ ô ð+J-ð4 ��Ø#Ø"Ø/Ø'ð	ñ ô ð5J-ð@ �-�-ØØ"Ø5Ø/ð	ñ ô ðAJ-ðL ��ØØØ&Ø4Ø&ðñ ô ðMJ-ðZ �=�=Ø#Ø$Ø)Ø/ð	ñ ô ð[J-ðf �m�mØØ;ðñ ô ðgJ-ðn ��Ø&ØEðñ ô ðoJ-ðv 
ˆ=ˆ=ØØEØ'ðñ ô ðwJ-ð@ �}�}ØØ(ðñ ô ðAJ-ðH ˆ}ˆ}ØØ+Ø?Ø+ð	ñ ô ðIJ-ðT ˆ}ˆ}Ø&Ø+ðñ ô ðUJ-ð\ �]�]Ø&Ø"Ø<ðñ ô ð]J-ðf �-�-Ø&Ø.ðñ ô ðgJ-ð J-ðn ��ØØ,ðñ ô ðoJ-ðv ˆ}ˆ}ØØ-ðñ ô ðwJ-ð~ ˜=˜=ØØ7ðñ ô ðJ-ðF ˆmˆmØØðñ ô ðGJ-ðN ��ØØØ0ðñ ô ðOJ-ðX �=�=ØØØ/ðñ ô ðYJ-ðb ˆMˆMØØØ,ðñ ô ðcJ-ðl �=�=ØØØ&ðñ ô ðmJ-ðv ˆmˆmØØØ*ðñ ô ðwJ-ð@ 
ˆ=ˆ=Ø#Ø/Ø'ðñ ô ðAJ-ðJ ˆmˆmØØ?Ø*ðñ ô ðKJ-ðT ˆmˆmØØ*ðñ ô ðUJ-ð\ ˜˜ØØ,ðñ ô ð]J-ðd ˆ]ˆ]ØØ7Ø)ðñ ô ðeJ-ðn 
ˆ=ˆ=ØØ'Ø:Ø'ð	ñ ô ðoJ-ðz ��ØØ-ØAðñ ô ð{J-ðD ˆmˆmØ#Ø<Ø5Ø*ð	ñ ô ðEJ-ð J-ðP ˆ}ØØ+Ø5Ø+ð	ñ ô ð "�MØØ1Ø*ðñ ô ð #�]ØØ1ðñ ô ð ˆ}Ø$Øðñ ô ð ˆmØØðñ ô ðMJ-ð J-ð J-€ð Jð Jð Jñ Jð` ðð ð ð ð ñ ô ñ „ðð&DàˆlðDð
 
ˆ5ðDð ˆEðDð ˆEðDð ˆUðDð ˆEðDð ˆEðDð ˆEðDð �+ðDð �ðDð  �+ð!Dð" �kð#Dð( 
ˆ8ð)Dð* �(ð+Dð, �Hð-Dð. �ð/Dð4 Ðð5Dð Dð6 Ð$ð7Dð8 Ð'ð9Dð: Ð!ð;Dð@ ˆIðADðB ˜9ðCDðH �\ðIDðJ �,ðKDðP ˆkðQDðR �;ðSDðX ÐðYDðZ Ðð[Dð\ ˜-ð]Dðb �(ðcDðd �ðeDðf ˜ðgDðl �JðmDðn 
ˆ:ðoDð Dð Dðt 	ˆ-ðuDðv �}ðwDð| �ð}Dð~ �ðDð@ �FðADðF �ðGDðL �ðMDðN ˆiðODðP ˆIðQDðR �YðSDðT Ð+ðUDðV Ð+ðWDðX Ð0ðYDð^ 	ˆ-ð_Dð` �MðaDðb �}ðcDðh �ðiDð Dð Dðj �ðkDðp ˆHðqDðr �8ðsDðx Ð!ðyDðz Ð"ð{Dð| Ð'ð}Dð~ Ð%ðDðD 
ˆ9ðEDðF �9ðGDðH �iðIDðJ ˆiðKDðP �ðQDðR ˆwðSDðX �ðYDðZ �ð[Dð` �KðaDðb 	ˆ+ðcDð Dðh ð  ØØð ØØØØØØØðGDð Dð D€ð Dð Dð Dñ DðV$Ø	Ðð$à
ˆMð$ð �Nð$ð Ð'ð	$ð
 Ð"ð$ð ˆmð$ð 
ˆ;ð$ð ˆð$ð Ðð$ð Ð*ð$ð �ð$ð Ðð$ð ˆ}ð$ð Ð ð$ð �Nð$ð  Ð8ð!$Ð ð ð ð ñ ð. &Ø.Ø(Ø*ð	)ð )Ð ð ð ð ñ ñ!ð !ð !ð !ð 6:ð Ið Iñ Ið Ið Ið IñXð ð ð ñ$1ð 1ð 1ð 1ð& -6¨IàØð7ñ -ô -Ð ð ð ð ñ ñ(ð (ð (ð (ñ$=ð =ð =ð =ñ*#ñ #ð #ð #ð #ñLñ ð ð ð ñ&!ñ !ð !ð !ð !ñL$ð $ð $ð $ñN
Vñ 
Vð 
Vð 
Vð 
Vð ññ ð ð ð ñ&Lð Lð Lð Lðb 04Ø7;ñdñ dñ dð dð dð dð dr!   