+
    kHàjå.  ã                   ó¦  a€ R t 0 t R t^ RIt^ RIHt ^ RIHtHt ^ RIH	t	H
t
 ^ RIHt ^ RIHt ^ RIHt ^ RIHt ]P&                  ! ]4      tRs] ^ k RtR	 R
 ltR R ltRRRRRR/tRt] U UUu/ uF&  p ]P9                  4        F  w  rW,           W3bK  	  K(  	  uppp t] ^k  ! R R]4      t]! RRR RRRRRR!R7	      t]! ]4       R# u uppp i )"zOpenRouter provider profile.N)ÚAny)Úget_affinity_scopeÚget_conversation_context)ÚGROK_AGGREGATOR_MODEL_PREFIXESÚis_fork_cache_scope)Úcodex_supported_efforts)Ú_cache_scope_from_session_id)Úregister_provider)ÚProviderProfilec                ó>   € V ^8„  d   QhR\         R,          R\        /# )é   ÚmodelNÚreturn)ÚstrÚbool)Úformats   "ÚP/home/ubuntu/.hermes/hermes-agent/plugins/model-providers/openrouter/__init__.pyÚ__annotate__r       s"   € ÷ Qñ Q¬S°4­Zð Q¼Dñ Qó    c                ó  a€ T ;'       g    RP                  4       oSP                  R4      '       g
   RS9  d   R# \        ;QJ d-    V3R l\         4       F  '       g   K   R'       * # 	  R'       * # ! V3R l\         4       4      '       * # )zRTrue for Anthropic models that reject any disable-thinking form (unknown -> True).Ú ÚclaudeFc              3   ó,   <"  € T F	  qS9   x € K  	  R # 5i)N© )Ú.0ÚsubÚms   & €r   Ú	<genexpr>Ú4_anthropic_reasoning_is_mandatory.<locals>.<genexpr>%   s   øé € ÐPÑ'O ˜!–8Ó'Oùs   ƒT)z
anthropic/r   )ÚlowerÚ
startswithÚanyÚ(_ANTHROPIC_REASONING_OPTIONAL_SUBSTRINGS)r   r   s   &@r   Ú!_anthropic_reasoning_is_mandatoryr#       se   ø€ à	�ˆ�"×ÑÓ€AØ�<‰<Ð0×1Ò1°hÀaÔ6GÙß‹sÔPÕ'OÓP�sŒsÔPÐPŠsÔPÐPˆsÔPÕ'OÓPÓPÔPÐPr   c                óL   € V ^8„  d   QhR\         R,          R\         R,          /# )r   Ú
session_idNr   )r   )r   s   "r   r   r   (   s&   € ÷ jñ jœC $�Jð j¬3°­:ñ jr   c                ó`   € \        \        4       ;'       g    \        4       ;'       g    T 4      # )uÞ   Declared routing scope, then ambient conversation, then explicit session_id.
Aux call sites (compression, titles, vision, MoAâ€¦) pass no ``session_id``,
so the ambient lineage ROOT keeps them pinned to their conversation.)r   r   r   )r%   s   &r   Ú_sticky_keyr'   (   s(   € ô (Ô(:Ó(<×(hÐ(hÔ@XÓ@Z×(hÐ(hÐ^hÓiÐir   r   z-fastz-flexc                   ó®   a a€ ] tR t^<t oRt]V3R lR l4       tRRRRRR/V3R	 lV 3R
 llltRR/V3R lR lltRRRRRRRR/V3R lR llt	Rt
VtV ;t# )ÚOpenRouterProfileuM   OpenRouter aggregator â€” provider preferences, reasoning config passthrough.c                ót   <€ V ^8„  d   QhRS[ S[S[3,          RS[R,          RS[ S[S[3,          R,          /# )r   Úcfgr   Nr   )Údictr   r   )r   Ú__classdict__s   "€r   r   ÚOpenRouterProfile.__annotate__@   s?   ø€ ÷ +ñ +©©c±3¨h­ð +ÁÀdÅ
ð +ÉtÑTWÑY\ÐT\Í~Ð`dÕOdñ +r   c           	     ó|  € V P                  R4      pV P                  R4      RJ ;'       g    VR8H  pV'       g   V'       g   V #  ^ RIHp ^ RIHp V! V4      pV'       d   VP                  R4      '       g   V # V'       dU   T;'       g    RP                  R	4      ;'       d    R\        V4      9  pVP                  R
4      '       g	   V'       d   R# T # V! W&P                  R4      4      pT'       d5   Y‚8w  d/   \        P                  RY(YP                  R4      4       / T CRT/Cp T #   \         d    T u # i ; i)ak  Clamp ``cfg["effort"]`` to the model's catalog-advertised levels.

Returns None when the config is a disable and the catalog marks the
route reasoning-mandatory (the caller omits the field).

OpenRouter's /v1/models entries publish ``reasoning.supported_efforts``
per model (ported from PrimeIntellect-ai/prime-agent#1258). Sending an
unsupported effort (e.g. ``ultra`` to a route that stops at ``high``)
yields provider 4xx errors; clamp to the nearest LOWER supported level
instead. No-op when the catalog is unreachable, the model is unlisted,
or no supported_efforts list is published (None = all levels accepted).
ÚeffortÚenabledFÚnone)Ú#clamp_reasoning_effort_to_supported)Ú'openrouter_model_reasoning_capabilitiesÚsupports_reasoningr   zopenai/Ú	mandatoryNÚsupported_effortsuT   openrouter: clamped reasoning effort %r â†’ %r for %s (catalog supported_efforts=%s))
ÚgetÚhermes_cli.modelsr3   Ú hermes_cli.models_reasoning_capsr4   r    r   Ú	ExceptionÚloggerÚdebug)	r+   r   r0   Údisabledr3   r4   ÚcapsÚ
no_disableÚclampeds	   &&       r   Ú_clamp_reasoning_to_catalogÚ-OpenRouterProfile._clamp_reasoning_to_catalog?   s  € ð —‘˜Ó"ˆØ—7‘7˜9Ó%¨Ð.×BÐB°&¸FÑ2BˆßŸhØˆJð	ÝMÝ`á:¸5ÓAˆDß˜tŸx™xÐ(<×=Ò=Ø�
÷ Ø#Ÿk˜k r×5Ñ5°iÓ@×qÐqÀVÔSjÐkpÓSqÑEq�
Ø#Ÿx™x¨×4Ò4¿
�tÐKÈÐKÙ9ØŸ™Ð!4Ó5óˆG÷
 �wÔ(Ü�L‰LØfØ ¯©Ð1DÓ(Eôð -�SÐ,˜( GÑ,ˆCØˆ
øô ô 	ØŠJð	úsN   ÁD+ Á!D+ Á8D+ Á:D+ ÂD+ ÂD+ Â$%D+ Ã
D+ ÃD+ ÃD+ ÃD+ Ä+D;Ä:D;Úapi_keyNÚbase_urlÚtimeoutg       @c          	      ól   <€ V ^8„  d   QhRS[ R,          RS[ R,          RS[RS[S[ ,          R,          /# )r   rD   NrE   rF   r   )r   ÚfloatÚlist)r   r-   s   "€r   r   r.   m   s>   ø€ ÷ ñ Ù �*ðÙ7:¸TµzðÙSXðá	‰c��TÕ	ñr   c               ó²   <€ \         e   \         #  \        SV `	  RW#R7      pTe   Ts T#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)z�Public OpenRouter catalog (no auth), cached per process. Tool-call
filtering happens in hermes_cli/models.py, which the picker reaches first.N)rD   rE   rF   zfetch_models(openrouter): %s)Ú_CACHEÚsuperÚfetch_modelsr;   r<   r=   )ÚselfrD   rE   rF   ÚresultÚexcÚ	__class__s   &$$$  €r   rM   ÚOpenRouterProfile.fetch_modelsm   s_   ø€ ô ÒÜˆMð	Ü‘WÑ)°$ÀÐ)Ó[ˆFð ÒØˆFØˆøô ô 	Ü�L‰LÐ7¸Ô=Ýûð	ús   ‘* ªAµAÁAr%   c                óP   <€ V ^8„  d   QhRS[ R,          RS[RS[S[ S[3,          /# )r   r%   NÚcontextr   )r   r   r,   )r   r-   s   "€r   r   r.   ~   s3   ø€ ÷ ñ ©c°D­jð ÉCð ÑTXÑY\Ñ^aÐYaÕTbñ r   c               ó¢  € / p\        V4      pV'       d   WCR &   VP                  R4      p\        P                  VP                  R4      ;'       g    R4      pV'       da   V^ ,          VP                  R4      8X  d"   T;'       g    / P                  R4      '       g#   / T;'       g    / CR\        V^,          4      /CpV'       d   WSR&   VP                  R4      pVP                  R4      ;'       g    RR8X  d9   Ve5   VR8w  d.    \	        V4      pVe   R	Tu;8:  d   R
8:  d   M V# RRRV/.VR&   V#   \
        \        3 d    Rp L8i ; i)r%   Úprovider_preferencesr   r   ÚonlyÚproviderÚopenrouter_min_coding_scorezopenrouter/pareto-codeNg        g      ð?Úidzpareto-routerÚmin_coding_scoreÚplugins)r'   r8   ÚOPENROUTER_ENDPOINT_PINSrI   rH   Ú	TypeErrorÚ
ValueError)	rN   r%   rT   ÚbodyÚ
sticky_keyÚprefsÚpinÚscoreÚscore_fs	   &$,      r   Úbuild_extra_bodyÚ"OpenRouterProfile.build_extra_body~   s=  € Ø!ˆô ! Ó,ˆ
ßØ!+�ÑØ—‘Ð2Ó3ˆÜ&×*Ñ*¨7¯;©;°wÓ+?×+EÐ+EÀ2ÓFˆ÷ ˜˜A� '§+¡+¨gÓ"6Ô6¸E¿K¸KÀR×;LÑ;LÈV×;TÒ;TØ;˜Ÿ˜ Ð; f¬d°3°qµ6«lÑ;ˆEßØ$�Ñà—‘Ð9Ó:ˆØ�K‰K˜Ó ×&Ð& BÐ+CÔCÈÒHYÐ^cÐgiÔ^iðÜ ›,�ð Ò" s¨gÖ'<¸Ö'<àˆð %)¨/Ð;MÈwÐ#WÐ"X��Y‘Øˆøô	 œzÐ*ô Ø’ðús   Ä
D8 Ä8EÅEÚreasoning_configr5   Fr   c                óª   <€ V ^8„  d   QhRS[ R,          RS[RS[R,          RS[R,          RS[RS[S[ S[S[3,          S[ S[S[3,          3,          /# )r   rh   Nr5   r   r%   rT   r   )r,   r   r   r   Útuple)r   r-   s   "€r   r   r.   ˜   se   ø€ ÷ 4%ñ 4%Ù#'¨$¥;ð4%ÙKOð4%á�T�zð4%á.1°D­jð4%áLOð4%ñ 
‰t‘C™�H�~™t¡C© H�~Ð-Õ	.ñ4%r   c               ó€  € / p/ p\         P                  T;'       g    R4      pV'       d   V^ ,          V8w  d   V^ ,          VR&   V'       dŠ   \        V4      '       dH   T;'       g    / p	V	P                  R4      p
V	P                  RR4      RJd   V
'       d   V
R8w  d   W§R&   M1Ve%   V P                  \	        V4      V4      pVe   W¶R	&   M	RRRR
/VR	&   \        V4      p\        VP                  R4      4      '       d
   VR,          pV'       d+   V'       d#   VP                  \        4      '       d   RV/VR&   Wg3# )zŒPass reasoning_config as extra_body.reasoning; pin Grok's cache via x-grok-conv-id;
rewrite speed-tier slugs to their OpenRouter base model.r   r   r0   r1   TFr2   Ú	verbosityÚ	reasoningÚmediumÚcache_scope_idzx-grok-conv-idÚextra_headers)	r]   r8   r#   rB   r,   r'   r   r    r   )rN   rh   r5   r   r%   rT   Ú
extra_bodyÚ	top_levelrc   r+   r0   rA   Úgrok_conv_ids   &$$$$,       r   Úbuild_api_kwargs_extrasÚ)OpenRouterProfile.build_api_kwargs_extras˜   s/  € ð &(ˆ
Ø$&ˆ	Ü&×*Ñ*¨5¯;¨;°BÓ7ˆß�3�q•6˜U”?Ø!$ Q¥ˆI�gÑßô( 1°×7Ò7Ø&×,Ð,¨"�ØŸ™ Ó*�Ø—7‘7˜9 dÓ+°5Ó8¿VÈÐRXÔHXØ-3˜kÑ*øØ!Ò-Ø×:Ñ:ÜÐ)Ó*¨Eó�ð Ò&Ø.5˜{Ñ+øà+4°d¸HÀhÐ*O�
˜;Ñ'ä" :Ó.ˆô ˜wŸ{™{Ð+;Ó<×=Ò=Ø"Ð#3Õ4ˆLßŸE e×&6Ñ&6Ô7U×&VÒ&VØ*:¸LÐ)IˆI�oÑ&ØÐ$Ð$r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚstaticmethodrB   rM   rf   rt   Ú__static_attributes__Ú__classdictcell__Ú__classcell__)rQ   r-   s   @@r   r)   r)   <   s}   ù‡ € ÙWà÷+ó ð+ðZØ'+ðØDHðØ[^÷õ ð"¸4÷ ò ð44%Ø15ð4%ØRWð4%à ð4%à;?÷4%÷ 4%ò 4%r   r)   Ú
openrouterÚ
OpenRouteru*   OpenRouter â€” unified API for 200+ modelszhttps://openrouter.ai/keyszhttps://openrouter.ai/api/v1z#https://openrouter.ai/api/v1/models)	ÚnameÚaliasesÚenv_varsÚdisplay_nameÚdescriptionÚ
signup_urlrE   Ú
models_urlÚfallback_modelsc                óê   € V ^8„  d   Qh/ ^ \         9   d   \        \        ,          R,          ;R&   ^\         9   d9   \        \        \        \        \        \        R3,          3,          3,          ;R&   # )r   NrK   .r]   )Ú__conditional_annotations__rI   r   r,   rj   )r   s   "r   r   r      sW   € × "Ñ "÷  Ò ŒŒS�	�DÕÑ ñ #÷lò œ$œs¤E¬#¬u´S¸#°X­Ð*>Õ$?Ð?Õ@ñ òm #r   )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)ÚopenaiÚazurezazure/us)zopenai/fast)zopenai/flex)zopenai/gpt-6-astrazopenai/gpt-6-astra-pro)Úor)ÚOPENROUTER_API_KEY)zanthropic/claude-sonnet-4.6zopenai/gpt-5.4zdeepseek/deepseek-chatzgoogle/gemini-3.8-flashzgoogle/gemini-3.7-flashzqwen/qwen3-plus)!rŠ   rz   ÚloggingÚtypingr   Úagent.portal_tagsr   r   Úagent.prompt_cache_scoper   r   Úagent.reasoning_effortr   Úagent.transports.codexr   Ú	providersr	   Úproviders.baser
   Ú	getLoggerrv   r<   rK   r"   r#   r'   Ú_SPEED_TIER_ENDPOINTSÚ_SPEED_TIERED_BASESÚitemsr]   r)   r   r   )ÚbaseÚsuffixÚtagsrŠ   s   000@r   Ú<module>rž      sô   øðÞ "ã Ý ç Jß XÝ :Ý ?Ý 'Ý *à	×	Ò	˜8Ó	$€à€Ó ð,Ð (õQõjð Ð<¸gÐGWÐY`ÐbrÐsÐ ØFÐ á,?õDÙ,? DÐTi×ToÑToÖTqÁLÀF€D…M�D�<ÒÑTq�MÑ,?óDÐ ó ô
P%˜ô P%ñf Ø	˜wÐ1HÐWcØ<ÐIeØ+Ð8]ðô	€
ñ �*Ö ùôEDs   Á1,C