Ë
    âß²já  ã                  ó²   — d Z ddlmZ ddlZddlZddlmZm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mZmZmZmZmZ dZd	d
œdd„Zdd„Zdd„Zdddœdd„Zy)u_  OpenRouter OAuth PKCE login (``hermes auth add openrouter --type oauth``).

Contract: https://openrouter.ai/docs/guides/overview/auth/oauth. The browser is sent to
``/auth?callback_url=...&code_challenge=...&code_challenge_method=S256``; the redirect carries
``?code=``; ``POST /api/v1/auth/keys`` swaps ``{code, code_verifier, code_challenge_method}`` for
``{"key": "sk-or-v1-..."}`` â€” a plain user-controlled API key, no refresh token. OpenRouter echoes no
``state`` parameter, so the CSRF nonce rides in the loopback callback PATH: a redirect to any other
path is a 404 and never reaches the exchange.
é    )ÚannotationsN)ÚAnyÚDict)Ú	urlencode)ÚOPENROUTER_AUTH_KEYS_URLÚOPENROUTER_AUTH_URLÚOPENROUTER_OAUTH_DOCS_URLÚ_openrouter_errÚhttpx)Ú_bind_loopback_callback_serverÚ_can_open_graphical_browserÚ_is_remote_sessionÚ_make_loopback_callback_handlerÚ_pkce_code_challengeÚ_pkce_code_verifierÚ_serve_loopback_callbacki   g      4@)Útimeout_secondsc               óv  — 	 t        j                  t        | |ddœddi|¬«      }|j
                  d	k(  rt	        d
dd¬«      ‚|j
                  dk\  rL|j                  j                  «       dt         }t	        d|j
                  › d�|rd|› �z   d«      ‚dz   d«      ‚	 |j                  «       }t        |t        «      r,t        |j                  d«      xs d«      j                  «       nd}|st	        dd«      ‚|S # t        $ r}t	        d|› �d«      |‚d}~ww xY w# t        $ r}t	        dd«      |‚d}~ww xY w)z\Exchange the authorization code for an API key; the key never enters a log or error message.ÚS256)ÚcodeÚcode_verifierÚcode_challenge_methodzContent-Typezapplication/json)ÚjsonÚheadersÚtimeoutz!OpenRouter code exchange failed: Ú openrouter_token_exchange_failedNi“  zrOpenRouter rejected the authorization code (invalid, already used, or older than 10 minutes). Run the login again.Ú openrouter_token_exchange_deniedT)Úrelogini�  z&OpenRouter code exchange failed (HTTP z).z Response: Ú z2OpenRouter code exchange returned a non-JSON body.Ú!openrouter_token_exchange_invalidÚkeyz:OpenRouter code exchange response did not include a 'key'.)r   Úpostr   Ú	Exceptionr
   Ústatus_codeÚtextÚstripÚ_ERROR_BODY_LIMITr   Ú
ValueErrorÚ
isinstanceÚdictÚstrÚget)r   r   r   ÚresponseÚexcÚdetailÚpayloadr!   s           ú?/home/ubuntu/.hermes/hermes-agent/hermes_cli/auth_openrouter.pyÚ_openrouter_exchange_coder2      s…  € ðvÜ—:‘:Ü$Ø¨}ÐW]ñ,_à#Ð%7Ð8À/ôSˆð ×Ñ˜sÒ"Üð#Ø$FÐPTôVð 	Vð ×Ñ˜sÒ"Ø—‘×$Ñ$Ó&Ð'9Ô(9Ð:ˆÜØ4°X×5IÑ5IÐ4JÈ"ÐMÑkqÐS^Ð_eÐ^fÐQgÑzØ.ó0ð 	0ØwyÑzØ.ó0ð 	0ðpØ—-‘-“/ˆô 4>¸gÄtÔ3LŒ#ˆg�k‰k˜%Ó Ò& BÓ
'×
-Ñ
-Ô
/ÐRT€CÙÜØHÐJmóoð 	oà€Jøô+ ò vÜÐ AÀ#ÀÐGÐIkÓlÐruÐuûðvûô ò pÜØ@ÐBeógØloð	pûðpús/   ‚#C< ÂD Ã<	DÄDÄDÄ	D8Ä&D3Ä3D8c                óx   — ddl m} t        d| › d�«        |d«      j                  «       }|st	        dd«      ‚|S )zeRemote/SSH: OpenRouter shows the code on screen when ``callback_url`` is omitted; the user pastes it.r   )Úmasked_secret_promptu‘   Remote session detected â€” using OpenRouter's headless flow.
Open this URL in a browser on any machine, authorize, then paste the code shown:
  ú
zAuthorization code: zNo authorization code entered.Úopenrouter_auth_no_code)Úhermes_cli.secret_promptr4   Úprintr&   r
   )Úauth_urlr4   r   s      r1   Ú_openrouter_headless_coder:   :   sP   € å=Ü	ð	_Ø_gÐ^hÐhjð	lômñ  Ð 6Ó7×=Ñ=Ó?€DÙÜÐ>Ð@YÓZÐZØ€Kó    c               ó¦  — t        j                  d«      }d|› �}t        |d¬«      \  }}t        dd|t        d¬«      }d	|j
                  d
   › |› �}t        › dt        d|i| ¥«      › �}	t        d|	› dt        › �«       |r/t        «       r%	 t        j                  |	«      }
t        |
rdnd«       t        d«       t        |||t        d¬«      }|j                  d«      r%t	        d|j                  d«      xs |d   › �d«      ‚t!        |j                  d«      xs d«      j#                  «       }|st	        dd«      ‚|S # t        $ r d}
Y Œ­w xY w)Né   z
/callback/Ú
OpenRouter)Údisplay_namez	127.0.0.1r   Úopenrouter_callback_bind_failed)ÚerrÚbind_failed_codezhttp://127.0.0.1:é   ú?Úcallback_urlz5Open this URL to authorize Hermes with OpenRouter:
  z

Docs: Fz,Browser opened for OpenRouter authorization.z<Could not open the browser automatically; use the URL above.z&Waiting for the OpenRouter callback...Úopenrouter_callback_timeout)r   rA   Útimeout_codeÚerrorz!OpenRouter authorization failed: Úerror_descriptionÚopenrouter_auth_deniedr   r   z8OpenRouter callback did not carry an authorization code.r6   )ÚsecretsÚtoken_urlsafer   r   r
   Úserver_addressr   r   r8   r	   r   Ú
webbrowserÚopenr#   r   r,   r+   r&   )Úauth_url_paramsÚopen_browserr   ÚnonceÚpathÚhandler_clsÚresultÚserverÚredirect_urir9   ÚopenedÚcallbackr   s                r1   Ú_openrouter_loopback_coderZ   F   sy  € Ü×!Ñ! "Ó%€EØ˜�wÐ€DÜ9¸$È\ÔZÑ€K�Ü+Ø�Q˜¬ÐKlôn€Fà& v×'<Ñ'<¸QÑ'?Ð&@ÀÀÐG€LÜ%Ð& a¬	°>À<Ð2cÐSbÐ2cÓ(dÐ'eÐf€Hä	ÐBÀ8À*ÈJÔWpÐVqÐ
rÔsÙÔ3Ô5ð	Ü—_‘_ XÓ.ˆFô 	ÁÑ<ØQô	Sä	Ð
2Ô3Ü'Ø�¨¼_Ø2ô4€Hð ‡|�|�GÔÜØ/°·±Ð=PÓ0QÒ0fÐU]Ð^eÑUfÐ/gÐhØ$ó&ð 	&ô ˆx�|‰|˜FÓ#Ò) rÓ*×0Ñ0Ó2€DÙÜÐXÐZsÓtÐtØ€Køô ò 	ØŠFð	ús   ÂE ÅEÅETg     Àr@©rQ   r   c           	     óÜ   — t        «       }t        |«      ddœ}t        «       r$t        t        › dt        i |¥ddi¥«      › �«      }nt        || |¬«      }t        d«       dt        ||«      iS )	zSRun the PKCE flow and return ``{"api_key": ...}`` for the credential-pool add path.r   )Úcode_challenger   rD   Ú	key_labelzhermes-agentr[   z>Exchanging the authorization code for an OpenRouter API key...Úapi_key)	r   r   r   r:   r   r   rZ   r8   r2   )rQ   r   r   Úparamsr   s        r1   Ú_openrouter_pkce_loginra   e   sw   € ä'Ó)€MÜ 4°]Ó CÐ^dÑe€FÜÔÜ(Ô,?Ð+@ÀÄ)ÐLsÈvÐLsÐWbÐdrÑLsÓBtÐAuÐ)vÓw‰ä(¨¸lÐ\kÔlˆÜ	Ð
JÔKØÔ0°°}ÓEÐFÐFr;   )r   r+   r   r+   r   ÚfloatÚreturnr+   )r9   r+   rc   r+   )rP   zDict[str, str]rQ   Úboolr   rb   rc   r+   )rQ   rd   r   rb   rc   zDict[str, Any])Ú__doc__Ú
__future__r   rK   rN   Útypingr   r   Úurllib.parser   Úhermes_cli.auth_constantsr   r   r	   r
   r   Úhermes_cli.auth_device_flowr   r   r   r   r   r   r   r'   r2   r:   rZ   ra   © r;   r1   ú<module>rl      se   ðñõ #ã Û ß Ý "÷fõ f÷j÷ jñ jð Ð ð Z^õ ó>	óð> 48ÐRWö 	Gr;   