
    PmjY'                         U d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	  ej
        e          Zdaee         dz  ed<   dZd	edz  d
efdZ G d de	          Z eddddddddd	  	        Z ee           dS )zOpenRouter provider profile.    N)Any)get_conversation_context)register_provider)ProviderProfile_CACHE)zclaude-3zclaude-opus-4-0zclaude-opus-4.0zclaude-opus-4-1zclaude-opus-4.1zclaude-sonnet-4-0zclaude-sonnet-4.0zclaude-opus-4-2025zclaude-sonnet-4-2025zclaude-opus-4-5zclaude-opus-4.5zclaude-sonnet-4-5zclaude-sonnet-4.5zclaude-haiku-4-5zclaude-haiku-4.5modelreturnc                     | pd                                                     d          sdvrdS t          fdt          D                        S )u  Return True for Anthropic models that reject any disable-thinking form.

    Claude 4.6+ (adaptive thinking) and newer named models have no "off"
    switch — sending ``reasoning: {enabled: false}`` makes OpenRouter emit
    ``thinking: {type: "disabled"}``, which these models 400 on. Unknown /
    new Anthropic model names default to mandatory so the next un-numbered
    release doesn't reintroduce the 400.
     )z
anthropic/clauder   Fc              3       K   | ]}|v V  	d S )N ).0subms     Q/home/thesage/.hermes/hermes-agent/plugins/model-providers/openrouter/__init__.py	<genexpr>z4_anthropic_reasoning_is_mandatory.<locals>.<genexpr>-   s'      PP3!8PPPPPP    )lower
startswithany(_ANTHROPIC_REASONING_OPTIONAL_SUBSTRINGS)r   r   s    @r   !_anthropic_reasoning_is_mandatoryr   !   se     
"A<<011 ha6G6GuPPPP'OPPPPPPPr   c                        e Zd ZdZdddddedz  dedz  dedee         dz  f fd	Zdd
dedz  dede	eef         fdZ
dddddde	dz  dededz  dedz  dedee	eef         e	eef         f         fdZ xZS )OpenRouterProfileuM   OpenRouter aggregator — provider preferences, reasoning config passthrough.Ng       @api_keybase_urltimeoutr   r   r   r	   c                    t           t           S 	 t                                          d||          }||a |S # t          $ r&}t                              d|           Y d}~dS d}~ww xY w)u|  Fetch from public OpenRouter catalog — no auth required.

        Note: Tool-call capability filtering is applied by hermes_cli/models.py
        via fetch_openrouter_models() → _openrouter_model_supports_tools(), not
        here. The picker early-returns via the dedicated openrouter path before
        reaching this method, so filtering here would be unreachable.
        Nr   zfetch_models(openrouter): %s)r   superfetch_models	Exceptionloggerdebug)selfr   r   r   resultexc	__class__s         r   r"   zOpenRouterProfile.fetch_models3   s     M	WW))$SZ)[[F!M 	 	 	LL7===44444	s   ); 
A+A&&A+)
session_idr*   contextc                n   i }t                      p|}|r||d<   |                    d          }|r||d<   |                    d          pd}|dk    rb|                    d          }|K|dk    rE	 t          |          }n# t          t          f$ r d }Y nw xY w|d|cxk    rd	k    rn n	d
|dg|d<   |S )Nr*   provider_preferencesproviderr   r   zopenrouter/pareto-codeopenrouter_min_coding_scoreg        g      ?zpareto-router)idmin_coding_scoreplugins)r   getfloat	TypeError
ValueError)	r&   r*   r+   body
sticky_keyprefsr   scorescore_fs	            r   build_extra_bodyz"OpenRouterProfile.build_extra_bodyM   s     "$ .//=:
 	,!+D233 	%$D W%%+,,,KK =>>E Ub[[##EllGG!:. # # #"GGG#&3'+@+@+@+@S+@+@+@+@+@.GLL'DO s   1B BBF)reasoning_configsupports_reasoningr   r*   r=   r>   r   c                Z   i }i }i }|rkt          |          r?|pi }	|	                    d          }
|	                    dd          dur|
r|
dk    r|
|d<   n|t          |          |d<   ndd	d
|d<   t                      p|}|r|r|                    d          r||d<   |r||d<   ||fS )a  OpenRouter passes the full reasoning_config dict as extra_body.reasoning.

        For xAI Grok models routed through OpenRouter, attach the
        ``x-grok-conv-id`` header so that xAI's prompt cache stays pinned to
        the same backend server across turns.
        effortenabledTFnone	verbosityN	reasoningmedium)rA   r@   )z
x-ai/grok-z	xai/grok-zx-grok-conv-idextra_headers)r   r3   dictr   r   )r&   r=   r>   r   r*   r+   
extra_body	top_levelrF   cfgr@   grok_conv_ids               r   build_api_kwargs_extrasz)OpenRouterProfile.build_api_kwargs_extras{   s    &(
$&	(* &	P6 177 P&,"** 779d++588V8RXHXHX-3Ik*!-*./?*@*@
;''6:h*O*O
;' 011?Z 	;E 	;e&6&67R&S&S 	;.:M*+ 	7)6Io&9$$r   )__name__
__module____qualname____doc__strr4   listr"   r   rG   r<   booltuplerL   __classcell__)r)   s   @r   r   r   0   sw       WW
 ##   t *	
  
cT	     6 +/, , , 4Z,;>,	c3h, , , ,b )-#( !%D% D% D% +D% !	D%
 TzD% $JD% D% 
tCH~tCH~-	.D% D% D% D% D% D% D% D%r   r   
openrouter)or)OPENROUTER_API_KEY
OpenRouteru*   OpenRouter — unified API for 200+ modelszhttps://openrouter.ai/keyszhttps://openrouter.ai/api/v1z#https://openrouter.ai/api/v1/models)zanthropic/claude-sonnet-4.6zopenai/gpt-5.4zdeepseek/deepseek-chatzgoogle/gemini-3.6-flashzqwen/qwen3-plus)	namealiasesenv_varsdisplay_namedescription
signup_urlr   
models_urlfallback_models)rP   loggingtypingr   agent.portal_tagsr   	providersr   providers.baser   	getLoggerrM   r$   r   rR   rQ   __annotations__r   rS   r   r   rV   r   r   r   <module>ri      s@   " " "        6 6 6 6 6 6 ' ' ' ' ' ' * * * * * *		8	$	$S	D   , (QS4Z QD Q Q Q QO% O% O% O% O% O% O% O%d 	$<++4  
$  *     r   