+
    „WÝjÎH  ã                   ó†  a € RJ t"0 t R t^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHtH	t	H
t
 ^ RIHtHtHt ]P                  ! R4      tRRRR/t] ^ k RKR R	 lltR
 R ltR R ltR R ltR R ltR R ltRRRRRRRRRRRR/RRRR RRRR!RR"RR/RR#RR$RR%RR&RR'RR/RR(RR)RRRR*RR+RR/RR,RR-RRRR.RR/RR/RR0RR1RR%RR2RR3R]/RR4RR5RR%RR6RR7R]/RR8RR9RR%RR:RR;R]/3t] ^k / t] ^k ]P4                  ! 4       tR< R= ltR> R? ltR@ RA lt]! R4      RB RC l4       t]! RD4      RE RF l4       t ]! RG4      RH RI l4       t!R# )Lz‚Dashboard OAuth/login-status helpers: provider catalog, per-provider device pollers,
Anthropic/Copilot/Claude-Code status probes.
N)ÚdatetimeÚtimezoneÚUTC)ÚAnyÚDictÚOptionalzhermes_cli.web_serverÚ	logged_inFÚsourcec                óR   € V ^8„  d   QhR\         \        ,          R\        R\        /# )é   ÚvalueÚvisibleÚreturn)r   ÚstrÚint)Úformats   "ÚOC:\Users\johnn\AppData\Local\hermes\hermes-agent\hermes_cli\web_server_oauth.pyÚ__annotate__r      s%   € ÷ <ñ <œ8¤C�=ð <´3ð <¼sñ <ó    c                ó  € V '       g   R# \        V 4      '       d   \        V \        4      '       g   R# \        V 4      pVP                  R4      ^8¼  d   VP	                  R^4      R,          p\        V4      V8:  d   V# RW!) R  2# )uØ   ``â€¦XXXXXX`` (last N chars) for UI display. JWTs show only the tail of the signature
segment. A callable (Azure Foundry Entra-ID bearer provider) is NEVER invoked â€” it yields
the ``<entra-id-bearer>`` placeholder.Ú z<entra-id-bearer>Ú.u   â€¦Néÿÿÿÿ)ÚcallableÚ
isinstancer   ÚcountÚrsplitÚlen)r   r   Úss   && r   Ú_truncate_tokenr      ss   € ÷ ÙÜ�‡‚œz¨%´×5Ò5Ù"ÜˆE‹
€AØ‡w�wˆsƒ|�qÔØ�H‰H�S˜!Ó˜RÕ ˆÜ�A“˜'Ô!ˆ1Ð;¨¨Q¨x¨y¨\¨NÐ';Ð;r   c          
      óŒ   € V ^8„  d   QhR\         R\         R\        \         \        3,          R\        \         \        3,          /# )r   r	   Úsource_labelÚcredsr   ©r   Údictr   )r   s   "r   r   r   #   s;   € ÷ ñ œ#ð ¬Sð ¼¼cÄ3¸h½ð ÌDÔQTÔVYÐQYÍNñ r   c                 óœ   € R RRV RVR\        VP                  R4      4      RVP                  R4      R\        VP                  R	4      4      /# )
r   Tr	   r!   Útoken_previewÚaccessTokenÚ
expires_atÚ	expiresAtÚhas_refresh_tokenÚrefreshToken)r   ÚgetÚbool)r	   r!   r"   s   &&&r   Ú_token_statusr.   #   sN   € à�T˜8 V¨^¸\Øœ¨¯©°=Ó)AÓBØ�e—i‘i Ó,Ð.AÄ4ÈÏ	É	ÐR`ÓHaÓCbðð r   c                óF   € V ^8„  d   QhR\         \        \        3,          /# ©r   r   ©r$   r   r   )r   s   "r   r   r   +   s   € ÷ ñ ¤¤c¬3 h¥ñ r   c                 ó  €  ^ RI Hp Hp V ! 4       pV'       d.   VP	                  R4      '       d   \        RRX! 4        R2V4      # Rp ^ RIHp VR,          P                  p^ R	IHp ^ R
IHp V FT  pV! V4      ;'       g    \        P                   ! V4      pV'       g   K3  RRRRRV V! V4       2R\#        V4      RRRR/u # 	  \%        \&        4      #   \         d    Rp LÕi ; i  \        \        3 d     L›i ; i)ub  Status for the "Anthropic Account" card: Hermes-managed PKCE file first, then the
registry-ordered env vars (process env â€” where Bitwarden-sourced secrets land â€” then .env).

Claude Code's ``~/.claude/.credentials.json`` is deliberately NOT read here; it has its own
``claude-code`` entry, and counting it here would shadow a real ANTHROPIC_API_KEY.
)Úread_hermes_oauth_credentialsÚ_get_hermes_oauth_fileNr'   Úhermes_pkcezHermes PKCE (Ú))ÚPROVIDER_REGISTRYÚ	anthropic)Úget_env_value)Úformat_secret_source_suffixr   Tr	   Úenv_varr!   r&   r(   r*   F)ÚANTHROPIC_API_KEYÚANTHROPIC_TOKENÚCLAUDE_CODE_OAUTH_TOKEN)Úagent.anthropic_credentialsr3   r4   Ú	Exceptionr,   r.   Úhermes_cli.authr7   Úapi_key_env_varsÚImportErrorÚKeyErrorÚhermes_cli.configr9   Úhermes_cli.env_loaderr:   ÚosÚgetenvr   r$   Ú_LOGGED_OUT)	r3   r4   Úhermes_credsÚenv_var_orderr7   r9   r:   Úvarr   s	            r   Ú_anthropic_oauth_statusrM   +   s  € ðßeÙ4Ó6ˆ÷ ˜×(Ñ(¨×7Ò7Ü˜]¨mÑ<RÓ<TÐ;UÐUVÐ,WÐYeÓfÐfà^€MðÝ5Ø)¨+Õ6×GÑGˆõ 0ÝAÛˆÙ˜cÓ"×4Ð4¤b§i¢i°£nˆß‰5à˜T 8¨Y¸È3È%ÑPkÐloÓPpÐOqÐHrØ¤°Ó!7¸ÀtÐM`Ðbgðò ñ ô ”ÓÐøô) ô ØŠðûô œÐ"ô Ùðús#   ‚C Á	C* ÃC'Ã&C'Ã*C>Ã=C>c                óF   € V ^8„  d   QhR\         \        \        3,          /# r0   r1   )r   s   "r   r   r   L   s   € ÷ ñ ¤$¤s¬C x¥.ñ r   c                 ó¨   €  ^ RI Hp Hp V! 4       pV'       d   V ! V4      '       d   \        RRV4      # \        \        4      #   \         d     Li ; i)zåClaude Code CLI credentials as their own entry, independent of the Anthropic card.

Connected follows the same local validity gate as Anthropic resolution. A
persisted access token that has already expired is not a usable login.
)Úis_claude_code_token_validÚread_claude_code_credentialsÚclaude_code_cliz~/.claude/.credentials.json)r?   rP   rQ   r.   r@   r$   rI   )rP   rQ   r"   s      r   Ú_claude_code_only_statusrS   L   sW   € ð	÷	
ñ -Ó.ˆßÑ/°×6Ò6Ü Ð!2Ð4QÐSXÓYÐYô ”ÓÐøô ô Ùðús   ‚A ™A §A ÁAÁAc                óF   € V ^8„  d   QhR\         \        \        3,          /# r0   r1   )r   s   "r   r   r   _   s   € ÷ ñ œT¤#¤s (�^ñ r   c                 ó´  €  ^ RI Hp  V ! R4      ;'       g    / p\        VP	                  R4      4      p\        VP	                  R4      4      pV'       d   VP	                  R4      ;'       g    RpMEV'       d<   VP	                  R4      ;'       g    VP	                  R4      ;'       g    R	pR
V R2pMRpRVRRRVRRRRRRRV/#   \         d    / p L¼i ; i)uö   Status for copilot-acp. ``logged_in`` only on positive evidence (env token or known on-disk
store); the CLI may hold its session in an OS keychain Hermes can't read, so the unverified
state reads "managed by the Copilot CLI" â€” never signed out.)Ú$get_external_process_provider_statusúcopilot-acpÚauth_verifiedÚ
configuredÚauth_sourcezCopilot credentials detectedÚresolved_commandÚcommandÚcopilotz#Managed by the GitHub Copilot CLI (r6   z$GitHub Copilot CLI not found on PATHr   r	   Úcopilot_clir!   r&   Nr(   r*   F)rA   rV   r@   r-   r,   )rV   ÚstatusÚverifiedrY   r!   Úfounds         r   Ú_copilot_acp_statusrb   _   sÝ   € ðÝHÙ5°mÓD×JÐJÈˆô �F—J‘J˜Ó/Ó0€HÜ�f—j‘j Ó.Ó/€JßØ—z‘z -Ó0×RÐRÐ4R‰ß	Ø—
‘
Ð-Ó.×TÐT°&·*±*¸YÓ2G×TÐTÈ9ˆØ<¸U¸GÀ1ÐE‰à=ˆà�X˜x¨¸ÈÐVeÐgkØ�dÐ/°¸Àjðð øô ô ØŠðús   ‚C —C ÃCÃCc                ó<   € V ^8„  d   QhR\         R\         R\         /# )r   Úprovider_idÚdefaultr   ©r   )r   s   "r   r   r   w   s!   € ÷ ñ ¬sð ¼Sð ÄSñ r   c                óš  €  ^ RI HpHp VP                  V 4      pV'       d   VP                  R8w  d   V# V! V 4      ;'       g    / p\        VP                  R4      ;'       g    R4      P                  4       pV'       d7   VP                  R^4      p\        V4      ^8”  d   RV^,           2MRpV V 2#  V#   \         d     T# i ; i)z±Render an external-process provider's sign-in command with the CLI actually configured
(``HERMES_COPILOT_ACP_COMMAND`` / ``COPILOT_CLI_PATH``); others get ``default`` untouched.)r7   rV   Úexternal_processr\   r   Ú )
rA   r7   rV   r,   Ú	auth_typer   ÚstripÚsplitr   r@   )	rd   re   r7   rV   Úpconfigr_   r\   ÚpartsÚtails	   &&       r   Ú_external_process_cli_commandrp   w   sÈ   € ðß[Ø#×'Ñ'¨Ó4ˆß˜'×+Ñ+Ð/AÔAØˆNÙ5°kÓB×HÐHÀbˆÜ�f—j‘j Ó+×1Ð1¨rÓ2×8Ñ8Ó:ˆßØ—M‘M # qÓ)ˆEÜ%(¨£Z°!¤^�Q�u˜Q•x�j‘>¸ˆDØ�Y˜t˜fÐ%Ð%ð ð €Nøô ô ØØ€Nðús-   ‚ B; £B; ¶B; ÁB; Á%B; Â5B; Â;C
Ã	C
ÚidÚnousÚnamezNous PortalÚflowÚdevice_codeÚcli_commandzhermes auth add nousÚdocs_urlzhttps://portal.nousresearch.comÚ	status_fnzopenai-codexzChatGPT or Codex Subscriptionzhermes auth add openai-codexz https://platform.openai.com/docsz
qwen-oauthzQwen (via Qwen CLI)Úexternalzhermes auth add qwen-oauthz#https://github.com/QwenLM/qwen-codeúminimax-oauthzMiniMax (OAuth)zhermes auth add minimax-oauthzhttps://www.minimax.ioú	xai-oauthz%xAI Grok OAuth (SuperGrok / Premium+)zhermes auth add xai-oauthz@https://hermes-agent.nousresearch.com/docs/guides/xai-grok-oauthrW   zGitHub Copilot (ACP)zcopilot loginz"https://docs.github.com/en/copilotr8   zAnthropic Accountzhermes auth add anthropicz.https://docs.claude.com/en/api/getting-startedzclaude-codezAAnthropic OAuth: Required Extra Usage Credits to Use Subscriptionzclaude setup-tokenz+https://docs.claude.com/en/docs/claude-codec                ó\   € V ^8„  d   QhR\         \        ,          R\         \        ,          /# )r   Úprofiler   )r   r   )r   s   "r   r   r   ´   s"   € ÷ ñ ¤¬#¥ð ´8¼Cµ=ñ r   c                 óx   € T ;'       g    R P                  4       pV'       d   VP                  4       R8X  d   R# V# )r   ÚcurrentN)rk   Úlower)r}   Ú	requesteds   & r   Ú_oauth_profile_namer‚   ´   s0   € Ø—�˜B×%Ñ%Ó'€Iß˜	Ÿ™Ó)¨YÔ6ÙØÐr   c                ó$   € V ^8„  d   QhR\         /# )r   Úlabelrf   )r   s   "r   r   r   »   s   € ÷ ñ œñ r   c                ó   a € V 3R lpV# )a  Wrap a device-code poller body ``fn(session_id, sess)``: vanished session is a no-op,
success marks ``approved``, any exception records ``error`` + ``error_message`` on the
session instead of raising (the thread has no caller; the dashboard reads the status).c                 óP   <a € \         P                  ! S 4      R  V V3R ll4       pV# )c                ó(   € V ^8„  d   QhR\         RR/# )r   Ú
session_idr   Nrf   )r   s   "r   r   Ú1_oauth_poller.<locals>.deco.<locals>.__annotate__Á   s   € ÷ 	3ñ 	3œsð 	3 tñ 	3r   c                 ó²  <€ \         ;_uu_ 4        \        P                  V 4      pR R R 4       X'       g   R #  S! W4       \         ;_uu_ 4        VR,          R8g  pV'       g   RVR&   R R R 4       X'       d"   \        P	                  RSVR,          V 4       R # \        P	                  RSV 4       R #   + '       g   i     L•; i  + '       g   i     Le; i  \
         ds   p^ RIHp \        P                  RSY4       T! Y4       \         ;_uu_ 4        RTR&   \        T4      TR	&   R R R 4        R p?R #   + '       g   i      R p?R # ; iR p?ii ; i)
Nr_   ÚpendingÚapprovedz,oauth/device: %s login ended %s (session=%s)z-oauth/device: %s login completed (session=%s))Únote_oauth_failurez+%s device-code poll failed (session=%s): %sÚerrorÚerror_message)
Ú_oauth_sessions_lockÚ_oauth_sessionsr,   Ú_logÚinfor@   Ú-hermes_cli.observability.shared_metrics_setupr�   Úwarningr   )rˆ   ÚsessÚsettledÚer�   Úfnr„   s   &    €€r   ÚpollerÚ+_oauth_poller.<locals>.deco.<locals>.pollerÀ   sø   ø€ ç%Ö%Ü&×*Ñ*¨:Ó6�÷ &çÙð3Ù�:Ô$ß)Ö)ð # 8�n°	Ñ9�Gß"Ø)3˜˜X™÷ *÷ Ü—I‘IÐLÈeÐUYÐZbÕUcÐeoÖpä—I‘IÐMÈuÐV`Öa÷ &×%ú÷ *×)ûô ô 3Ý\Ü—‘ÐJÈEÐS]ÔaÙ" 4Ô+ß)Ö)Ø%,�D˜‘NÜ,/°«F�D˜Ñ)÷ *×)×)×)Ò)þð	3úsd   �B3¹C ÁCÁ)C Á9C ÂC Â3C	ÃC	ÃC ÃEÃ$3EÄD9Ä+EÄ9EÅEÅEÅE)Ú	functoolsÚwraps)r™   rš   r„   s   f €r   ÚdecoÚ_oauth_poller.<locals>.deco¿   s*   ù€ Ü	�Š˜Ó	÷	3ð 	3ó 
ð	3ð0 ˆr   © )r„   rž   s   f r   Ú_oauth_pollerr¡   »   s   ø€ õð6 €Kr   c                óV   € V ^8„  d   QhR\         \        \        3,          R\        RR/# )r   r–   Ústater   Nr1   )r   s   "r   r   r   Ý   s.   € ÷ !Iñ !I¤¤S¬# X¥ð !I´sð !I¸tñ !Ir   c           	     ó  € \        VRR4      pVR9   d   R# \        ;_uu_ 4        VR8X  do   VP                  ;'       g    RV R&   VP                  '       d   VP                  MRV R&   \        VP                  4      V R&   VP                  V R&    RRR4       R# VR	8X  d   R	V R
&    RRR4       R# VR8X  d:   RRuV R
&   V R&   VP                  ;'       g    VP                  V R&    RRR4       R# RV R
&   \        VRR4      ;'       g    T;'       g    RV R&   VP                  V R&   \        \        VRR4      4      V R&   \        \        VR^ 4      ;'       g    ^ 4      V R&   RRR4       R#   + '       g   i     R# ; i)aa  Write one ``anon_auth.SignInState`` onto the dashboard session, under the sessions lock.

The whole desktop mapping lives here: the state carries its own copy, so nothing below turns a
reason into a string. ``completed`` deliberately leaves ``status`` on ``"pending"`` so the
:func:`_oauth_poller` wrapper stamps ``"approved"`` when the poller returns.
Úkindr   NÚ	completedÚaccount_emailÚmodelÚhandoffÚhandoff_statusÚ	cancelledr_   Ú	timed_outrŽ   ÚtimeoutÚreasonr�   Ú	retryableFÚretry_after)ÚcodeÚwaiting)Úgetattrr�   ÚemailÚmodel_changedr¨   Úlistr©   rª   ÚdetailÚcopyr-   r   )r–   r£   r¥   s   && r   Ú_record_sign_in_stater¹   Ý   sm  € ô �5˜& "Ó%€DØÐ"Ô"Ùß	Ö	Ø�;ÔØ$)§K¡K×$7Ð$7°4ˆD�Ñ!à+0×+>×+>Ð+>˜EŸKšKÀDˆD�‰Mä" 5§=¡=Ó1ˆD�‰Oà%*×%9Ñ%9ˆDÐ!Ñ"Ø÷ 
Ñ	ð �;ÔØ(ˆD�‰NØ÷ 
Ñ	ð �;ÔØ-4°iÐ*ˆD�‰N˜D ™Nà$)§L¡L×$>Ð$>°E·J±JˆD�Ñ!Ø÷# 
Ñ	ð$ !ˆˆX‰Ü  ¨°"Ó5×HÐH¸×HÐHÀˆˆX‰Ø %§
¡
ˆˆ_Ñä ¤¨°¸UÓ!CÓDˆˆ[ÑÜ!¤'¨%°ÀÓ"B×"GÐ"GÀaÓHˆˆ]Ñ÷/ 
×	×	Ò	ús<   ¥E0Á E0Á9E0ÂE0Â2$E0ÃE0Ã2E0Ä	E0ÄAE0Å0F	c                óV   € V ^8„  d   QhR\         R\        \         \        3,          RR/# ©r   rˆ   r–   r   Nr#   )r   s   "r   r   r     s)   € ÷ ñ ¤Sð ´´S¼#°Xµð À4ñ r   c           	     ó¢  € VP                  R4      pVf   R#  V F  p\        W4       K  	  \        P                  ! \        4      ;_uu_ 4        VP                  4        RRR4       R#   + '       g   i     R# ; i  \        P                  ! \        4      ;_uu_ 4        TP                  4        RRR4       i   + '       g   i     i ; i; i)a  Drain the sign-in the start route began: the one shared flow, rendered onto the session.

The generator was created and advanced to its ``Code`` state by ``_start_nous_device_code``, so
it is already holding the device code and its HTTP client. Nothing here is wrapped in
``_profile_scope``: that context manager holds a process-global lock and swaps module
attributes across its ``yield``, and this loop can last the sign-in code's whole expiry. The
generator scopes its own short config/auth-store sections instead.
Ú_sign_inN)r,   r¹   Ú
contextlibÚsuppressr@   Úclose)rˆ   r–   Úgenr£   s   &&  r   Ú_nous_sign_in_pollerrÂ     s„   € ð �(‰(�:Ó
€CØ
‚{ÙðÛˆEÜ! $Ö.ñ ô × Ò ¤×+Õ+Ø�I‰IŒK÷ ,×+×+Ò+ûŒZ× Ò ¤×+Õ+Ø�I‰IŒK÷ ,×+×+Ð+ýs/   ™A> ÁA*Á*A;	Á>#CÂ!B;	Â2	CÂ;CÃCÚminimaxc                óV   € V ^8„  d   QhR\         R\        \         \        3,          RR/# r»   r#   )r   s   "r   r   r     s)   € ÷ ,1ñ ,1¤ð ,1¬4´´S°­>ð ,1¸dñ ,1r   c           !     ó^  € ^ RI Hp ^ RIHpHpHpHpHp ^ RIpVR,          VR,          r©VP                  VP                  R4      RR/R	R
7      ;_uu_ 4       pV! W¹V
VR,          VR,          VR,          VP                  R4      R7      pRRR4       \        P                  ! \        4      pV! \        XR,          4      VR7      pRRRVP                  RR4      RV	RVRV
RVRVP                  RR4      RVR,          RVR,          RVP                  R4      RVP!                  4       R\        P"                  ! V\        R7      P!                  4       R \%        ^ \        WíP'                  4       ,
          4      4      /pV! VP                  R!4      4      ;_uu_ 4        \(        ;_uu_ 4        VP                  R"4      '       d   R"VR#&    RRR4       RRR4       R# V! V4       RRR4       RRR4       R#   + '       g   i     ELs; i  + '       g   i     L.; i  + '       g   i     R# ; i)$ae  MiniMax poller: PKCE-style ``code_verifier`` + ``user_code`` instead of Nous's
``device_code``. Builds the same auth_state as the CLI's ``_minimax_oauth_login`` and persists
via ``_minimax_save_auth_state`` so the system ends up as after ``hermes auth add minimax-oauth``.
Region is fixed to "global" here; cn-region operators use the CLI's ``--region cn``.©Ú_profile_scope)Ú_minimax_poll_tokenÚ"_minimax_resolve_token_expiry_unixÚ_minimax_save_auth_stateÚMINIMAX_OAUTH_GLOBAL_INFERENCEÚMINIMAX_OAUTH_SCOPENÚportal_base_urlÚ	client_idg      .@ÚAcceptúapplication/jsonT)r­   ÚheadersÚfollow_redirectsÚ	user_codeÚcode_verifierÚexpired_in_rawÚinterval_ms)ÚclientrÍ   rÎ   rÓ   rÔ   Ú
expired_inrÖ   rØ   )ÚnowÚproviderrz   ÚregionÚglobalÚinference_base_urlÚscopeÚ
token_typeÚBearerÚaccess_tokenÚrefresh_tokenÚresource_urlÚobtained_atr(   )ÚtzÚ
expires_inr}   r«   r_   )Úhermes_cli.web_server_profilesrÇ   rA   rÈ   rÉ   rÊ   rË   rÌ   ÚhttpxÚClientÚTimeoutr,   r   rÙ   r   r   Ú	isoformatÚfromtimestampÚmaxÚ	timestampr�   )rˆ   r–   rÇ   rÈ   rÉ   rÊ   rË   rÌ   rè   rÍ   rÎ   r×   Ú
token_datarÙ   Úexpires_at_tsÚ
auth_states   &&              r   Ú_minimax_pollerrò     sÜ  € õ >÷õ ó Ø!%Ð&7Õ!8¸$¸{Õ:K�YØ	�‰Ø—‘˜dÓ#¨hÐ8JÐ-KÐ^bð 
÷ 
ô 
à	Ù(ØÀiØ˜;Õ'°t¸OÕ7LØÐ,Õ-¸4¿8¹8ÀMÓ;Rô
ˆ
÷
ô �,Š,”sÓ
€CÙ6´s¸:ÀlÕ;SÓ7TÐZ]Ô^€Mà�OØ�$—(‘(˜8 XÓ.Ø˜?ØÐ<Ø�YØÐ$Ø�j—n‘n \°8Ó<Ø˜
 >Õ2Ø˜ OÕ4Ø˜
Ÿ™ ~Ó6Ø�s—}‘}“Ø”h×,Ò,¨]¼sÔC×MÑMÓOØ”c˜!œS ·±³Õ!@ÓAÓBð€Jñ 
˜Ÿ™ Ó+×	,Õ	,÷ "Ö!Ø�x‰x˜×$Ò$Ø!,��X‘Ø÷ "÷ 
-Ñ	,ñ % ZÔ0÷	 "÷ 
-Ñ	,÷3
÷ 
ð 
ú÷8 "×!ú÷ 
-×	,Ð	,ús<   Á3G4ÆHÆ*H	ÇHÇH	Ç"HÇ4H	ÈHÈHÈH,	Úxaic                óV   € V ^8„  d   QhR\         R\        \         \        3,          RR/# r»   r#   )r   s   "r   r   r   G  s.   € ÷ &Añ &A¤3ð &A¬d´3¼°8­nð &AÀñ &Ar   c                ó4  € ^ RI Hp ^ RIp^ RIHpHpHpHpHp V! R4      p	VP                  VP                  R4      RR/R7      ;_uu_ 4       p
V! W©R,          VR	,          \        ^<\        VR
,          \        P                  ! 4       ,
          4      4      \        VR,          4      R7      pRRR4       R\        XP                  RR4      ;'       g    R4      P!                  4       R\        VP                  RR4      ;'       g    R4      P!                  4       R\        VP                  RR4      ;'       g    R4      P!                  4       RVP                  R4      R\        VP                  R4      ;'       g    R4      P!                  4       ;'       g    R/pV! VP                  R4      4      ;_uu_ 4        \"        ;_uu_ 4        VP                  R4      '       d   RVR&    RRR4       RRR4       R# V! WÉRR\$        P&                  ! \(        4      P+                  4       P-                  RR4      R7       V! R4       V! RR	4       RRR4       RRR4       R#   + '       g   i     EL¼; i  + '       g   i     L.; i  + '       g   i     R# ; i)z3Background poller for xAI's OAuth device-code flow.rÆ   N)Ú_save_xai_oauth_tokensÚ_xai_oauth_discoveryÚ_xai_oauth_poll_device_tokenÚmark_provider_active_if_unsetÚunsuppress_credential_sourceg      4@rÏ   rÐ   )r­   rÑ   Útoken_endpointru   r(   Úinterval)rû   ru   ræ   Úpoll_intervalrá   r   râ   Úid_tokenræ   rß   rà   r}   r«   r_   Úoauth_device_codeFz+00:00ÚZ)Ú	discoveryÚ	auth_modeÚ
set_activeÚlast_refreshr{   )rç   rÇ   rè   rA   rö   r÷   rø   rù   rú   ré   rê   rí   r   Útimer   r,   rk   r�   r   rÙ   r   rë   Úreplace)rˆ   r–   rÇ   rè   rö   r÷   rø   rù   rú   r  r×   rï   Útokenss   &&           r   Ú_xai_device_pollerr  F  s  € õ >Û÷õ ñ
 % TÓ*€IØ	�‰˜eŸm™m¨DÓ1¸HÐFXÐ;Yˆ×	ZÔ	ZÐ^dÙ1ØÐ-=Õ#>ÈDÐQ^ÕL_Ü˜2œs 4¨Õ#5¼¿	º	»Õ#CÓDÓEÔUXÐY]Ð^hÕYiÓUjô
ˆ
÷ 
[ð 	œ˜JŸN™N¨>¸2Ó>×DÐDÀ"ÓE×KÑKÓMØœ˜ZŸ^™^¨O¸RÓ@×FÐFÀBÓG×MÑMÓOØ”C˜
Ÿ™ z°2Ó6×<Ð<¸"Ó=×CÑCÓEØ�j—n‘n \Ó2Ø”c˜*Ÿ.™.¨Ó6×BÐB¸(ÓC×IÑIÓK×WÐWÈxð€Fñ 
˜Ÿ™ Ó+×	,Õ	,×.BÖ.Bà�8‰8�K× Ò Ø(ˆD�‰NØ÷	 /C×	,Ñ	,ñ 	ØÐ3FÐSXÜ!Ÿš¤cÓ*×4Ñ4Ó6×>Ñ>¸xÈÓMõ	
ñ
 	& kÔ2ñ
 	% [°-Ô@÷! /C×	,Ñ	,÷ 
[×	ZÐ	Zú÷ /C×.Bú×	,×	,Ð	,ús>   ÁAIÆ;JÇ
I3	Ç(JÇ:AI3	ÉJÉI0	É3JÉ>JÊJ	c                ó2  € V ^8„  d   Qh/ ^ \         9   d   \        \        \        3,          ;R&   ^\         9   d(   \        \        \        \        3,          R3,          ;R&   ^\         9   d,   \        \        \        \        \        3,          3,          ;R&   # )r   rI   .Ú_OAUTH_PROVIDER_CATALOGr‘   )Ú__conditional_annotations__r$   r   r   Útuple)r   s   "r   r   r      sw   € ÷ ñ ÷" CÒ BŒT”#”s�(�^Ñ Bñ#÷^ò œœt¤C¬ H�~¨sÐ2Õ3ñ ñ_÷^ 0Ò /””cœ4¤¤S �>Ð)Õ*Ñ /ò_r   )é   )#r  Ú__doc__r¾   Úloggingrœ   rG   Ú	threadingr  r   r   r   Útypingr   r   r   Ú	getLoggerr’   rI   r   r.   rM   rS   rb   rp   r
  r‘   ÚLockr�   r‚   r¡   r¹   rÂ   rò   r  r   )r  s   @r   Ú<module>r     s"  øðöó Û Û Û 	Û Û ß ,Ñ ,ß &Ñ &ð ×ÒÐ0Ó1€ð  +¨E°8¸TÐB€Ó B÷<õõõBõ&õ0ð6 
ˆ6�6˜=¨&°-ÀÐPfØÐ2°KÀðGà	ˆ>˜6Ð#BÀFÈMØÐ2°JÐ@bØ�$ðð 
ˆ<˜Ð!6¸À
ØÐ0°*Ð>cØ�$ðð
 
ˆ?˜FÐ$5°v¸}ØÐ3°ZÐAYÐ[fÐhlðnð 
ˆ;˜Ð GÈÐQ^ØÐ/ØÐSÐU`Ðbfðhð
 
ˆ=˜&Ð"8¸&À*ÈmÐ]lØÐ5°{ÐDWðYð 
ˆ;˜Ð 3°V¸ZÈÐXsØÐAÀ;ÐPgðià	ˆ=˜&Ð"eØˆZ˜Ð(<ØÐ>ÀÐMeðgð97Ð ó ð@ .0€Ó /Ø —~’~Ó'Ð õõõD!IñH ˆvÓôó ðñ( ˆyÓô,1ó ð,1ñ^ ˆuÓô&Aó ò&Ar   