
    PL
j.Y                    8   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          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! edd"d#d$d%&          d' edd(d)d*          d+ edd,-          d. ed/d0-          d1 edd2d34          d5 edd67          d8 edd9d:d;<          d= ed/d>7          d? ed/dd@          dA ed/dB7          dC eddD7          i dE eddF7          dG eddH7          dI eddJ          dK edddLM          dN edddOM          dP edddQM          dR edddSM          dT edddUM          dV edddW          dX eddYdZW          d[ edd\7          d] edd^7          d_ edd`daW          db eddcddde<          df eddg7          dh eddi7          dj edkdlm          Zdnedo<   e G dp dq                      Zi drddsd1dtd1dud1dvd1dwdVdxdVdydVdzdddd{dd|dd}dXd~dXddXddXdd5i dd5dd5dd5dd8dd8ddAddAdd.dd.dd+dd+dd'ddIddIddIddKddKi ddNddNddPddPddPddCddEddEddEddEddGddGddGddddddRddRi ddRddTddTdd[dd[dd]dd]dd]dd]ddjddjddjddjdd_dd_ddbddbd!d!d!ddddddZded<   ddddddddddddŜZded<   dd/ddkdȜZded<   dd̈́ZddτZddфZddԄZdddׄZddڄZdd܄Zdd߄Z 	 	 ddd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       8/home/kuhnn/.hermes/hermes-agent/hermes_cli/providers.pyr   r   "   s         II"I""""MI&(N((((r!   r   
openrouterr   )OPENAI_API_KEYOPENROUTER_BASE_URL)r   r   r   r   nousoauth_device_codez)https://inference-api.nousresearch.com/v1)r   r   r   openai-codexcodex_responsesoauth_externalz%https://chatgpt.com/backend-api/codexz	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_URLzgoogle-gemini-clizcloudcode-pa://googlelmstudior   )
LM_API_KEYzhttp://127.0.0.1:1234/v1LM_BASE_URL)r   r   r   r   r   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_URL)r   r   r   zopencode-goOPENCODE_GO_BASE_URLkiloKILOCODE_BASE_URLhuggingfaceHF_BASE_URLnovitaNOVITA_BASE_URLxai)r   r   r   nvidiaz#https://integrate.api.nvidia.com/v1NVIDIA_BASE_URLxiaomiXIAOMI_BASE_URL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ollama-cloudOLLAMA_BASE_URLzazure-foundryAZURE_FOUNDRY_BASE_URLbedrockbedrock_converseaws_sdk)r   r   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    rl   r   r   r   rm   rn   r   r!   r"   rh   rh      s         CCGGGIIINNN%%%%HMICMMMMFr!   rh   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_planz
gemini-clizgemini-oauthhfzhugging-facezhuggingface-hubz	novita-ainovitaaimimozxiaomi-mimotencenttokenhubztencent-cloudtencentmaasawszaws-bedrockzamazon-bedrockamazonzarcee-aiarceeaiz	gmi-cloudgmicloudcustomlocal)r-   z	lm-studio	lm_studioollamavllmllamacppz	llama.cppz	llama-cppzDict[str, str]ALIASESzNous PortalzOpenAI CodexzGitHub Copilot ACPzStepFun Step PlanzXiaomi MiMoz	GMI CloudzTencent TokenHubz	LM StudiozLocal endpointzAWS BedrockzOllama Cloud)r&   r(   r0   r?   rW   r]   rY   r-   r   rc   r`   _LABEL_OVERRIDESchat_completions)r   r6   r)   rd   TRANSPORT_TO_API_MODErj   r   returnc                    |                                                                  }t                              ||          S )zResolve 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)rj   keys     r"   normalize_providerr     s1     **,,



C;;sC   r!   Optional[ProviderDef]c                   t          |           }	 ddlm}  ||          }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_infoNr   Fr   r   
models.dev)
ri   rj   r   rk   rl   r   r   r   rm   rn   hermes)	ri   rj   r   rk   rl   r   r   r   rn   )r   agent.models_devr   	Exceptionrf   r   r   r   r   r   r   listenvr   appendrh   rj   tupleapirm   r   )rj   	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"N9--		   			 !!),,G)0CG%%m	*1<&&u$+:w  3:Bw//9@HG55b 	&& 	(w- 	(, ( (X%%OOB'''"8__&7)-) 
 
 
 	
 !%%i;;'$3.$5!/'

 

 

 
	
 4s   # 22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   rj   )r   r   pdefs      r"   	get_labelr     sM    ";//I $$$	** 	""D yr!   providerr   c                6    t          |           }|r|j        ndS )z:Return True when the provider is a multi-model aggregator.F)r   r   )r   r   s     r"   r   r     s"    !!D!%0450r!   r   rl   c                8   t          |           }|p|rN|                    d                                          }d|v rdS |                    d          sd|v rdS d|v rdS t                              |j        d	          S | d
k    rdS |r|                    d                                          }t          |          }|                    d          s|dk    rdS |dk    rd|v rdS |dk    rdS |                    d          rt          |d          rdS d	S )u   Determine the API mode (wire protocol) for a provider/endpoint.

    Resolution order:
      1. Known provider → transport → TRANSPORT_TO_API_MODE.
      2. URL heuristics for unknown / custom providers.
      3. Default: 'chat_completions'.
    N/zapi.kimi.com/codingr6   z
/anthropiczapi.anthropic.comzapi.openai.comr)   r   rc   rd   zapi.kimi.comz/codingzbedrock-runtime.zamazonaws.com)
r   rstripr   endswithr   r   r   r   
startswithr
   )r   rl   r   	url_lowerhostnames        r"   determine_api_moder     sq    !!D  	) ,,2244I$	11++!!,// ,3F)3S3S++9,,(($((9KLLL 9!!  
&OOC((..00	$X..l++ 	(x;N/N/N''~%%)y*@*@'''''$$122 	&7LXWf7g7g 	&%%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 )zResolve 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.
    Nrj   r   r   urlrl   key_envr   r   Fr   user-configri   rj   r   rk   rl   r   r   rn   )
isinstancedictr   r   rh   r   )rj   r   entrydisplay_nameapi_urlr   r   r   s           r"   resolve_user_providerr   "  s(     jd;; tOOD!!EeT"" t 99VR((0DLiir""]eiir&:&:]eii
TV>W>W][]Gii	2&&,"G		+}55FIH !   x	 	 	 	r!   r   c                |    d|                                                                                      dd          z   S )zBuild a canonical slug for a custom_providers entry.

    Matches the convention used by runtime_provider and credential_pool
    (``custom:<normalized-name>``).  Centralised here so all call-sites
    produce identical slugs.
    zcustom: -)r   r   replace)r   s    r"   custom_provider_slugr   I  s7     |))++1133;;CEEEEr!   custom_providersOptional[List[Dict[str, Any]]]c                   |rt          |t                    sdS | pd                                                                }|sdS |dk    }d}|D ]}t          |t                    s|                    d          pd                                }|                    dd          p-|                    dd          p|                    dd          pd                                }|r|s|||f}t          |          }||                                |hvrt          ||dd	|d
dd          c S |r-|r+|\  }	}
t          |	          }t          ||	dd	|
d
dd          S dS )zIResolve a provider from the user's config.yaml ``custom_providers`` list.Nr   r   rj   rl   r   r   r   r   Fr   r   r   )r   r   r   r   r   r   r   rh   )rj   r   	requestedbare_custom_fallbackfirst_validr   r   r   slugdnameaurls              r"   resolve_custom_providerr   S  s   
  :.>#E#E t""$$**,,I t
 %0K! 
 
%&& 			&))/R6688IIj"%% yy##yy## 
%'' 	  	7 	 '1K#L11\//114888# 	
 	
 	
 		
 		
 		
  
 
!t#E**# 	
 	
 	
 		
 4r!   user_providersOptional[Dict[str, Any]]c                   t          |           }t          |          }||S |rLt          ||          }||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   r   r   r   )ri   rj   r   rk   rl   rn   )r   r   r   r   r   r   r   r   rh   rj   r   r   r   )	rj   r   r   r   r   	user_pdefcustom_pdefr   r   s	            r"   resolve_provider_fullr     s&   " #4((I 	""D  ))^DD	 )$**,,*<*<*>*>OO	  *$0@AAKHHHHHH"N9--	 ^'!*"#    !     4s   6B> >
C
C)rj   r   r   r   )rj   r   r   r   )r   r   r   r   )r   r   r   r   )r   )r   r   rl   r   r   r   )rj   r   r   r   r   r   )r   r   r   r   )rj   r   r   r   r   r   )NN)rj   r   r   r   r   r   r   r   )"r   
__future__r   loggingdataclassesr   typingr   r   r   r   r	   utilsr
   r   	getLoggerr   loggerr   rf   r    rh   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r"   <module>r      s3    & # " " " " "  ! ! ! ! ! ! 3 3 3 3 3 3 3 3 3 3 3 3 3 3 : : : : : : : :		8	$	$ $       g---*.	  g- MM%E  g- MM#"A  g-" #"/'	  #g-. --"5/	  /g-: "1  ;g-D &4&  Eg-R ==#$)/	  Sg-^ mm;  _g-f &E  gg-n 
==E'  og-x }}(  yg-@ }}+?+	  Ag-L }}&+  Mg-T ]]&"<  Ug-^ --&.  _g-f ,  gg- g-n }}-  og-v ==7  wg-~ mm  g-F 0  Gg-P ==/  Qg-Z MM,  [g-d ==&  eg-n mm*  og-x 
==#/'  yg-B mm?*  Cg-L mm*  Mg-T ,  Ug-\ ]]7)  ]g-f 
==':'	  gg-r MM*  sg-~ ]]1  g-F }}$  Gg- g- g g g gZ        &}l}
 
5} E} E} U} E} E} E} +} }  +!}" k#}( 
8)}* (+}, H-}. /}4 5} }6 $7}8 '9}: !;}@ IA}B 9C}H \I}J ,K}P kQ}R ;S}X Y}Z [}\ -]}b (c}d e}f g}l Jm}n 
:o} } }t 	-u}v }w}| }}~ }@ FA}F G}L M}N iO}P IQ}R YS}T +U}V +W}X 0Y}^ %_}` 'a}h 	-i}j Mk} } }l }m}r s}t u}z H{}| 8}}B !C}D "E}F 'G}H %I}N 
9O}P 9Q}R iS}T iU}Z [}\ w]}b c}d e} }j y} } } } } } }J "'"*"$ $     $ &.(*	) )     ! ! ! !C C C CL   $1 1 1 1' ' ' ' 'X$ $ $ $NF F F FB B B BN 047;8 8 8 8 8 8 8r!   