+
    jHàj6í ã                  ó®  a€ 0 t $ R t^ RIHt ^ RIHt ^ RIt^ RIt^ RI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 ^ RIHtHt ^ RIHt ^ RIHtHtHt ^ RIHt ^ R	IHtHtHtH t H!t!H"t"H#t#H$t$ ^ R
I%H&t& ^ RI'H(t(H)t)H*t* ^ RI+H,t, ^ RI-H.t.H/t/H0t0H1t1 ^ RI2H3t3H4t4H5t5H6t6H7t7H8t8 ^ RI9H:t:H;t; ^ RI<H=t=H>t>H?t?H@t@HAtAHBtBHCtCHDtDHEtEHFtFHGtGHHtHHItIHJtJ ^ RIKHLtLHMtMHNtNHOtOHPtPHQtQ ^ RIRHStSHTtTHUtUHVtVHWtWHXtXHYtYHZtZH[t[H\t\H]t]H^t^H_t_H`t`HataHbtbHctcHdtdHeteHftfHgtgHhthHitiHjtjHktkHltlHmtmHntnHotoHptpHqtqHrtrHstsHtttHutuHvtvHwtwHxtxHytyHztz ^ RI{H|t|H}t}H~t~HtH€t€H�t�H‚t‚HƒtƒH„t„H…t…H†t†H‡t‡Hˆtˆ ^ RI‰HŠtŠH‹t‹HŒtŒH�t�HŽtŽH�t�H�t�H‘t‘H’t’H“t“H”t”H•t•H–t–H—t— ^ RI˜H™t™HštšH›t›HœtœH�t�HžtžHŸtŸH t H¡t¡H¢t¢H£t£H¤t¤H¥t¥H¦t¦H§t§H¨t¨H©t© ^ RIªH«t« ^ RI¬H­t­ ^ RI®H¯t¯H°t°H±t±H²t²H³t³H´t´Hµtµ ^ RI¶H·t·H¸t¸H¹t¹HºtºH»t»H¼t¼H½t½H¾t¾H¿t¿HÀtÀHÁtÁHÂtÂHÃtÃHÄtÄHÅtÅHÆtÆHÇtÇHÈtÈHÉtÉHÊtÊHËtËHÌtÌHÍtÍHÎtÎHÏtÏHÐtÐHÑtÑHÒtÒHÓtÓHÔtÔHÕtÕHÖtÖH×t×HØtØHÙtÙHÚtÚHÛtÛHÜtÜHÝtÝHÞtÞHßtßHàtà ]EPÂ                  ! ]â4      tã ^ RIätä ^ RIætæR R ltçR R ltè] ! R R4      4       téERíR! R" lltê. ]é! R#R$R%]º]»]¼]¾R&7      N]é! R'R(R)]ÃR*7      NERîN]é! R+R,R)]ÄR*7      N]é! R-R.R)]ÌR*7      NERïNR0R1]ÍERðR23N]é! R3R4R5]ÎR6R77      NERñNERòNERóNERôNR<R=]ÒERõR>3NERöNER÷NRARB]ÐERøRC3NERùN]é! RDRERF]Ç]É]Å]ÆRGRHRI]ÈRJ]Ê/RK7      NERúNERûNERüNERýNERþNERÿNER NERNERNERNERNERNERNERNERNRYRZ]ÏER	R[3NER
NERNERN5tëR_]ìR`&   Ra ]ë 4        U u/ uF  q EPÚ                  V bK  	  up tîRb]ìRc&   ]ï! ]î4      tð^ RdIñHòtòHótóHôtôHõtõHötö ^ ReI÷HøtøHùtúHûtû ]û! 4        Rf Rg ltü0 ERmtýERtþRh Ri ltÿRj^/Rk Rl llEt RmER/EtRn]ìRo&   Rp Rq lEtRr Rs lEtRt Ru lEtRv Rw lEtRx Ry lEtRz R{ lEtR| R} lEtR~RR€R�/Et	]ï! E]	4      0 ERm,          Et
R‚ Rƒ lEtR„ R… lEtR† R‡ lEtRˆ R‰ lEtRŠ R‹ lEt/ EtRŒ]ìR�&   ]EP"                  ! 4       EtRŽ R� lEtR� R‘ lEtR’ R“ lEtR” R• lEtR– R— lEt]ï! R˜ ]EP0                  ]EP2                  E]! ]R™R4      3 4       4      EtRš R› lEtRœ R� lEtRž RŸ lEtR  R¡ lEt]R¢ R£ l4       Et ]]¹3R¤R/R¥ R¦ lll4       Et!R§ R¨ lEt"ERR© Rª llEt#R«R¬/R­ R® llEt$ERR¯ R° llEt%R± R² lEt&R³ R´ lEt'Rµ R¶ lEt(R· R¸ lEt)]]¹3R¹ Rº ll4       Et*R»R¼/R½ R¾ llEt+R¿ RÀ lEt,RÁ RÂ lEt-R»R¬/RÃ RÄ llEt.RÅ RÆ lEt/RÇ RÈ lEt0RÉ RÊ lEt1RË RÌ lEt2RÍ RÎ lEt3ERRÏ RÐ llEt4EREt5EREt6RÑ RÒ lEt7RÓ RÔ lEt8RÕRRÖR¬/R× RØ llEt9RÙ RÚ lEt:RÛ RÜ lEt;RÝRRÞRRßR/Rà Rá llEt<Râ Rã lEt=Rä Rå lEt>Ræ Rç lEt?Rè Ré lEt@Rê Rë lEtARì Rí lEtBRî Rï lEtCRð Rñ lEtDRò Ró lEtERô Rõ lEtFRö R÷ lEtG]ï! RM04      EtH]ï! 0 ERm4      EtIEREtJRø Rù lEtKRú Rû lEtLRü Rý lEtMRþ Rÿ lEtNE]DR¼3E]FR¼3E]LR¬3E]GR¼3E]NR¼33EtOER ]ìER&   ER ER lEtPERER ER llEtQER ER lEtRER ER	 lEtSER
 ER lEtT/ ERR9bERR9bERR9bERR9bERR8bERR8bERR8bERRPbERRPbERRPbR+R+bERR+bERR+bERR+bERR:bERR:bERR:b/ ERR;bERR;bERR<bERR<bER R?bER!R?bER"R@bER#R@bER$RAbER%RAbER&RAbER'RObER(RObER)RDbER*RDbER+RDbER,RNbC/ ER-RNbER.RNbER/RLbER0RLbER1R0bER2R0bER3R0bER4R0bER5R3bER6R3bER7RQbER8RQbER9RQbER:RRbER;RRbER<R-bER=R-bC/ R-R-bER>RUbER?RUbER@RUbERARVbERBRVbERCRWbERDRWbERERWbERFRWbERGRXbERHRXbERIR\bERJR\bERKR\bERLR\bERMRSbC/ ERNRSbERORTbERPRTbERQRTbR/R/bERRR/bERSR/bERTR'bERUR'bERVERWbERXERWbERYRYbERZERWbER[ERWbER\ERWbER]ERWbCEtUER^]ìER_&   ER` ERa lEtVERb ERc lEtWERd ERe lEtXERfR¬/ERg ERh llEtYERi ERj lEtZ]ï! R0R/04      Et[ERk ERl lEt\ERERmRERnRERfR¬/ERo ERp lllEt]ERq ERr lEt^ERs ERt lEt_ERu ERv lEt`ERw ERx lEtaERyR/ERz ER{ llEtbEREtcER| ER} lEtdER~ ER lEteER€ ER� lEtf]ï! 0 ERm4      EtgER‚]ìERƒ&   ]EP"                  ! 4       Eth/ EtiER„]ìER…&   ER†EtjER‡ERˆER‰RERŠRER‹]Á/ERŒ ER� llEtkERŽ ER� lEtlERˆEtmREsnER�]ìER‘&   REsoER’]ìER“&   ER” ER• lEtpER– ER— lEtqER˜ ER™ lEtr]! R¼ERš7       ! ER› ERœ4      4       Ets]ï! 0 ERm4      Ett]ï! 0 ERm4      EtuR#E]s! R#ER�ERžE]tE]u,          R¼ERŸ7      R'E]s! R'ER ER¡E]tER¢ER£0,          R¼ERŸ7      R+E]s! R+ER¤ER¥]ï! ER¦ER§04      R¼ERŸ7      R-E]s! R-ER¨ER©4      RDE]s! RDERªER«4      /EtvER¬]ìER­&   ER® ER¯ lEtw]! E]wR#ER°7      Etx]! E]wR+ER°7      Ety]! E]wR'ER°7      EtzER± ER² lEt{ER³ ER´ lEt|ERµ ER¶ lEt}ER· ER¸ lEt~ER¹ ERº lEtER» ER¼ lEt€ER½ ER¾ lEt�ER¿ ERÀ lEt‚ERÁ ERÂ lEtƒERÃ ERÄ lEt„ERERÅ ERÆ llEt…/ E]vEP                  4        UUu/ uF  w  rWEP                  bK  	  uppCR^ERÇ/CEtˆER^]ìERÈ&   R5ERÉR ERÊR]ERËR%ERÌR)ERÌ/Et‰ER^]ìERÍ&   ERÎ ERÏ lEtŠERÐ ERÑ lEt‹ERÒ ERÓ lEtŒR:]6R;]6R9]7R0E]ŒR/ERÔ RAERÕ /Et�ERÖ]ìER×&   ERØ ERÙ lEtŽERÚ ERÛ lEt�ERERÜR¬/ERÝ ERÞ lllEt�ERß ERà lEt‘ERá ERâ lEt’ERã ERä lEt“ERå ERæ lEt”ERç ERè lEt•ERé ERê lEt–ERë ERì lEt—R#   ]å d    Rtä E	Li ; i  ]å d    Rtæ E	L"i ; iu up i u uppi (  a  Multi-provider authentication system for Hermes Agent.

- ``ProviderConfig`` / ``PROVIDER_REGISTRY`` describe every known inference provider.
- The auth store (``~/.hermes/auth.json``) holds per-provider state, the credential pool and
  suppression markers; ``_auth_store_lock`` / ``_load_auth_store`` / ``_save_auth_store`` are the
  only I/O primitives (cross-process flock, atomic 0o600 writes).
- ``resolve_provider()`` picks the active provider via the documented priority chain.
- ``OAUTH_PROVIDER_FLOWS`` maps each OAuth provider to its resolver/status builder; the flows live in
  ``auth_nous``/``auth_codex``/``auth_xai``/``auth_qwen``/``auth_minimax``/``auth_openrouter`` and are
  re-imported here so ``hermes_cli.auth.<name>`` stays the public/patchable surface.)Úannotations)Úinstall_hintN)Ú	ExitStackÚcontextmanager)Ú	dataclassÚfield)Úpartial)ÚdatetimeÚtimezoneÚUTC)ÚPath)ÚAnyÚCallableÚDictÚ	FrozenSetÚIterableÚListÚOptionalÚTuple)Úurlparse)ÚOPENROUTER_BASE_URLÚhermes_home_keyÚsecure_parent_dir)Ú$sanitize_borrowed_credential_payload)Úatomic_json_writeÚ	env_floatÚfile_signatureÚis_truthy_value)ÚKIMI_CODE_BASE_URLÚZAI_ENDPOINTSÚ$_normalize_lmstudio_runtime_base_urlÚ_resolve_kimi_base_urlÚ_resolve_zai_base_urlÚdetect_zai_endpoint)Ú_prompt_model_selectionÚ_save_model_choice)Ú_can_open_graphical_browserÚ_default_verifyÚ_is_remote_sessionÚ!_nous_device_auth_timeout_messageÚ!_offer_existing_oauth_credentialsÚ_poll_device_token_genericÚ_poll_for_tokenÚ_print_device_code_instructionsÚ_print_login_successÚ_print_loopback_ssh_hintÚ_prompt_yes_noÚ_request_device_codeÚ_resolve_verifyÚ_ssh_user_at_host)Ú!SINGLE_USE_REFRESH_POOL_PROVIDERSÚ_oauth_heal_clean_marksÚ_oauth_heal_noticesÚconsume_oauth_heal_noticesÚ#heal_forked_single_use_oauth_grantsÚ$strip_cloned_single_use_oauth_grants)(ÚNOUS_SESSION_TERMINALÚNOUS_SESSION_UNKNOWNÚNOUS_SESSION_VALIDÚ_ALLOWED_NOUS_INFERENCE_HOSTSÚ_agent_key_is_usableÚ_apply_nous_refreshed_tokensÚ!_assert_nous_inference_jwt_usableÚ_compute_nous_auth_statusÚ#_format_nous_entitlement_auth_errorÚ_healed_nous_inference_urlÚ_login_nousÚ_merge_shared_nous_oauth_stateÚ_migrate_stale_nous_portal_urlÚ_nous_device_code_loginÚ_nous_inference_env_overrideÚ_nous_invoke_jwt_is_usableÚ_nous_invoke_jwt_statusÚ_nous_portal_base_urlÚ_nous_portal_env_overrideÚ_nous_shared_store_lockÚ_nous_shared_store_pathÚ_pool_first_oauth_statusÚ_quarantine_nous_oauth_stateÚ_quarantine_nous_pool_entriesÚ_read_shared_nous_stateÚ_refresh_access_tokenÚ_refresh_nous_or_quarantineÚ_select_nous_invoke_jwtÚ_sync_nous_pool_from_auth_storeÚ_token_fingerprintÚ_try_import_shared_nous_stateÚ)_validate_nous_inference_url_from_networkÚ_write_shared_nous_stateÚfetch_nous_modelsÚget_nous_auth_status_localÚget_nous_session_validityÚpersist_nous_credentialsÚrefresh_nous_oauth_from_stateÚ resolve_nous_runtime_credentialsÚstep_up_nous_billing_scope)Ú_MINIMAX_OAUTH_ERROR_BODY_LIMITÚ_login_minimax_oauthÚ_minimax_oauth_loginÚ_minimax_pkce_pairÚ_minimax_poll_tokenÚ_minimax_post_formÚ_minimax_request_user_codeÚ"_minimax_resolve_token_expiry_unixÚ_minimax_response_error_textÚ_minimax_save_auth_stateÚ_refresh_minimax_oauth_stateÚ"build_minimax_oauth_token_providerÚ)resolve_minimax_oauth_runtime_credentials)Ú_login_xai_oauthÚ_read_xai_oauth_tokensÚ_refresh_xai_oauth_tokensÚ_save_xai_oauth_tokensÚ'_write_through_xai_oauth_to_global_rootÚ_xai_access_token_is_expiringÚ_xai_oauth_device_code_loginÚ_xai_oauth_discoveryÚ_xai_oauth_poll_device_tokenÚ_xai_oauth_request_device_codeÚ#_xai_proactive_refresh_skew_secondsÚ _xai_validate_inference_base_urlÚrefresh_xai_oauth_pureÚ%resolve_xai_oauth_runtime_credentials)Ú_codex_access_token_is_expiringÚ_codex_device_code_loginÚ_codex_http_clientÚ_codex_pool_rate_limit_statusÚ_codex_quota_probe_cacheÚ_codex_usage_probe_urlÚ_import_codex_cli_tokensÚ_is_codex_rate_limit_shapedÚ_login_openai_codexÚ_probe_codex_quota_restoredÚ_read_codex_tokensÚ_refresh_codex_auth_tokensÚ"_refresh_expired_codex_probe_tokenÚ_save_codex_tokensÚ clear_codex_pool_quota_cooldownsÚrefresh_codex_oauth_pureÚ!resolve_codex_runtime_credentials)Ú_openrouter_pkce_login)Únote_store_write)Ú_qwen_access_token_is_expiringÚ_qwen_cli_auth_pathÚ_read_qwen_cli_tokensÚ_refresh_qwen_cli_tokensÚ_save_qwen_cli_tokensÚget_qwen_auth_statusÚ resolve_qwen_runtime_credentials)*Ú_decode_jwt_claimsÚAUTH_STORE_VERSIONÚAUTH_LOCK_TIMEOUT_SECONDSÚDEFAULT_NOUS_PORTAL_URLÚDEFAULT_NOUS_INFERENCE_URLÚDEFAULT_NOUS_CLIENT_IDÚNOUS_BILLING_MANAGE_SCOPEÚDEFAULT_NOUS_SCOPEÚNOUS_DEVICE_CODE_SOURCEÚNOUS_AUTH_PATH_INVOKE_JWTÚ!ACCESS_TOKEN_REFRESH_SKEW_SECONDSÚNOUS_INVOKE_JWT_MIN_TTL_SECONDSÚDEFAULT_CODEX_BASE_URLÚDEFAULT_XAI_OAUTH_BASE_URLÚMINIMAX_OAUTH_CLIENT_IDÚMINIMAX_OAUTH_SCOPEÚMINIMAX_OAUTH_GLOBAL_BASEÚMINIMAX_OAUTH_CN_BASEÚMINIMAX_OAUTH_GLOBAL_INFERENCEÚMINIMAX_OAUTH_CN_INFERENCEÚ"MINIMAX_OAUTH_REFRESH_SKEW_SECONDSÚDEFAULT_QWEN_BASE_URLÚDEFAULT_GITHUB_MODELS_BASE_URLÚDEFAULT_COPILOT_ACP_BASE_URLÚDEFAULT_OLLAMA_CLOUD_BASE_URLÚDEFAULT_ACTUAL_BASE_URLÚDEFAULT_ACTUAL_LOCAL_BASE_URLÚSTEPFUN_STEP_PLAN_INTL_BASE_URLÚSTEPFUN_STEP_PLAN_CN_BASE_URLÚCODEX_OAUTH_CLIENT_IDÚCODEX_OAUTH_TOKEN_URLÚ'CODEX_ACCESS_TOKEN_REFRESH_SKEW_SECONDSÚXAI_OAUTH_CLIENT_IDÚXAI_OAUTH_SCOPEÚ%XAI_ACCESS_TOKEN_REFRESH_SKEW_SECONDSÚ&QWEN_ACCESS_TOKEN_REFRESH_SKEW_SECONDSÚLMSTUDIO_NOAUTH_PLACEHOLDERÚACTUAL_LOCAL_NOAUTH_PLACEHOLDERÚCODEX_RATE_LIMITED_CODEÚ	AuthErrorÚ	_nous_errÚhttpxc               ó    € V ^8„  d   QhRRRR/# )é   Úbase_urlÚstrÚreturnÚbool© )Úformats   "Ú4/home/ubuntu/.hermes/hermes-agent/hermes_cli/auth.pyÚ__annotate__rÊ   u   s   € ÷ @ñ @ sð @¨tñ @ó    c                ó¾   €  \        T ;'       g    R4      P                  ;'       g    RP                  4       P                  R4      pTR9   #   \         d     R# i ; i)z5Return True for Actual's loopback local API endpoint.Ú Ú.F>   Ú	localhostú::1ú0.0.0.0ú	127.0.0.1)r   ÚhostnameÚlowerÚrstripÚ	Exception)rÃ   Úhosts   & rÉ   Úis_actual_local_base_urlrØ   u   s[   € ðÜ˜Ÿ˜ RÓ(×1Ñ1×7Ð7°R×>Ñ>Ó@×GÑGÈÓLˆð Ð?Ñ?Ð?øô ô Úðús   ‚A �A ¨ A ÁAÁAc               ó    € V ^8„  d   QhRRRR/# )rÂ   rÃ   rÄ   rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ~   s   € ÷ ñ ¨ð °ñ rË   c                ó°  € \        T ;'       g    R4      P                  4       P                  R4      pV'       g   \        #  \	        V4      pVP
                  ;'       g    RP                  4       P                  R4      pVP                  P                  R4      pTR9   d"   TR8X  g   \        T4      '       d
   TR,           # T#   \         d    Tu # i ; i)z¨Return Actual's OpenAI-compatible base URL (hosted api.actual.inc or the loopback local server;
both expose a /v1 surface for the selected OpenAI-compatible transport).rÍ   Ú/rÎ   zapi.actual.incz/v1>   rÍ   rÛ   )
rÄ   ÚstriprÕ   r°   r   rÓ   rÔ   ÚpathrÖ   rØ   )rÃ   ÚurlÚparsedr×   rÝ   s   &    rÉ   Únormalize_actual_base_urlrà   ~   s»   € ô ˆh�nˆn˜"Ó
×
#Ñ
#Ó
%×
,Ñ
,¨SÓ
1€CßÜ&Ð&ðÜ˜#“ˆØ—‘×%Ð% 2×,Ñ,Ó.×5Ñ5°cÓ:ˆØ�{‰{×!Ñ! #Ó&ˆð ˆyÔ˜dÐ&6Ô6Ô:RÐSV×:WÒ:WØ�U�{ÐØ€Jøô	 ô ØŠ
ðús   ÁC Á ;C ÃCÃCc                  óª   € ] tR t^‘t$ RtR]R&   R]R&   R]R&   RtR]R&   RtR]R&   RtR]R	&   Rt	R]R
&   ]
! ]R7      tR]R&   RtR]R&   RtR]R&   RtR# )ÚProviderConfigz%Describes a known inference provider.rÄ   ÚidÚnameÚ	auth_typerÍ   Úportal_base_urlÚinference_base_urlÚ	client_idÚscope)Údefault_factoryúdict[str, Any]ÚextraÚtupleÚapi_key_env_varsÚbase_url_env_varrÇ   N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__ræ   rç   rè   ré   r   Údictrì   rî   rï   Ú__static_attributes__rÇ   rË   rÉ   râ   râ   ‘   sa   ‡ á/ØƒGØ
ƒIØƒNØ€O�SÓØ Ð˜Ó Ø€IˆsÓØ€Eˆ3ƒOÙ!°$Ô7€Eˆ>Ó7Ø Ð�eÓ ØÐ�c×rË   râ   Úapi_keyc               ó4   € V ^8„  d   Qh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È   s   "rÉ   rÊ   rÊ       sM   € ÷ Nñ NØðNØðNØ,/ðNØCHðNàðNà+.ðNà?MñNrË   c           	     ó   € \        WWRW4R7      # )z@Compact constructor for the common env-var-keyed provider shape.)rã   rä   rå   rç   rî   rï   )râ   )rã   rä   rç   rî   rï   rå   s   &&&&&&rÉ   Ú_api_key_providerrû       s   € ô Ø IØ)ôNð NrË   ÚnouszNous PortalÚoauth_device_code)ræ   rç   rè   ré   úopenai-codexzOpenAI CodexÚoauth_external)rç   ú	xai-oauthz%xAI Grok OAuth (SuperGrok / Premium+)z
qwen-oauthz
Qwen OAuthÚlmstudioÚcopilotzGitHub CopilotÚCOPILOT_API_BASE_URLúcopilot-acpzGitHub Copilot ACPÚexternal_processÚCOPILOT_ACP_BASE_URL)rç   rï   ÚgeminiÚzaiúkimi-codingúkimi-coding-cnÚstepfunzStepFun Step PlanÚSTEPFUN_BASE_URLÚarceeÚgmiÚactualzActual ComputerÚACTUAL_BASE_URLúminimax-oauthu   MiniMax (OAuth Â· minimax.io)Úoauth_minimaxÚregionÚglobalÚcn_portal_base_urlÚcn_inference_base_url)ræ   rç   rè   ré   rì   Ú	anthropicÚCLAUDE_CODE_OAUTH_TOKENúalibaba-coding-planú
minimax-cnÚxaiú
ai-gatewayúopencode-zenúopencode-goÚkilocodeÚhuggingfaceÚxiaomiútencent-tokenhubútencent-tokenplanzollama-cloudzOllama CloudÚOLLAMA_BASE_URLÚbedrockÚaws_sdkúazure-foundryztuple[Any, ...]Ú_REGISTRY_ROWSc              #  ód   "  € T F&  p\        V\        4      '       d   TM\        V!  x € K(  	  R # 5i©N)Ú
isinstancerâ   rû   )Ú.0Úrs   & rÉ   Ú	<genexpr>r.  ø   s+   é € ÐlÑ]kÐXYœ: a¬×8Ò8‘aÔ>OÐQRÑ>SÔSÓ]kùs   ‚.0zdict[str, ProviderConfig]ÚPROVIDER_REGISTRY)Úatomic_config_replaceÚget_hermes_homeÚget_config_pathÚread_raw_configÚ$require_readable_config_before_write)Úget_plugin_oauth_auth_statusÚregistry_lookupÚsync_plugin_provider_registryc               ó   € V ^8„  d   QhRR/# ©rÂ   rÅ   rÄ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s   € ÷ 
dñ 
d˜3ñ 
drË   c                 óx   a€ ^ RI Ho \        R,          P                  p \	        R V3R lV  4        4       R4      # )uu  First usable Anthropic credential (``.env`` preferred over a stale shell export), or ``""``.

Order mirrors ``PROVIDER_REGISTRY["anthropic"].api_key_env_vars``.

Checks both the ``.env`` file and the process environment, preferring ``~/.hermes/.env`` so a deliberate
key rotation isn't shadowed by a stale shell export (matches the api-key resolution path â€” see #20591).
©Úget_env_value_prefer_dotenvr  c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir*  rÇ   ©r,  Úvs   & rÉ   r.  Ú$get_anthropic_key.<locals>.<genexpr>  s   é € Ð^ÑX�qÓ\]—’ÓXùó   ‚	�
c              3  óH   <"  € T F  pS! V4      ;'       g    R x € K  	  R# 5i©rÍ   NrÇ   )r,  Úvarr<  s   & €rÉ   r.  r@    s"   øé € ÐXÉxÈÑ8¸Ó=×CÐCÀÔCËxùs   ƒ"—"rÍ   )Úhermes_cli.configr<  r/  rî   Únext)Úenv_varsr<  s    @rÉ   Úget_anthropic_keyrH    s2   ø€ õ >Ü  Õ-×>Ñ>€HÜÑ^ÔXÉxÔXÓ^Ð`bÓcÐcrË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   ÚvaluerÄ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   &  s   € ÷ >ñ > ð >¨ñ >rË   c                ój  € V P                  4       pVP                  R4      '       d   VP                  R4      '       d   R# \         Fq  pVP                  V4      '       g   K  V\	        V4      R pV'       g   K4  \
        ;QJ d    R V 4       F  '       d   K   RM	  RM! R V 4       4      '       g   Kp   R# 	  VP                  RR4      P                  R	R4      P                  R
R4      p\        V4      ;'       d5    \
        ;QJ d    R V 4       F  '       d   K   R# 	  R# ! R V 4       4      # )zETrue for the placeholder shapes shipped in .env.example and the docs.Úyour_Ú_hereTNc              3  ó*   "  € T F	  qR 8H  x € K  	  R# 5i©ÚxNrÇ   ©r,  Úcs   & rÉ   r.  Ú(_is_placeholder_shape.<locals>.<genexpr>.  s   é € Ð3©d¨ žH«dùó   ‚FÚ rÍ   Ú-Ú_c              3  ó*   "  € T F	  qR 8H  x € K  	  R# 5irO  rÇ   rQ  s   & rÉ   r.  rS  1  s   é € Ð!=±H¨q s¦(³HùrT  )rÔ   Ú
startswithÚendswithÚ_PLACEHOLDER_KEY_PREFIXESÚlenÚallÚreplacerÆ   )rJ  ÚloweredÚprefixÚtailÚstrippeds   &    rÉ   Ú_is_placeholder_shaperc  &  så   € à�k‰k‹m€GØ×Ñ˜'×"Ò" w×'7Ñ'7¸×'@Ò'@Ùß+ˆØ×Ñ˜f×%Ô%Øœ3˜v›;˜<Ð(ˆDß‰tŸ›Ñ3©dÓ3ŸŸšÑ3©dÓ3×3Ô3Úñ	 ,ð
 �‰˜s BÓ'×/Ñ/°°RÓ8×@Ñ@ÀÀbÓI€HÜ�‹>×=Ð=Ÿc›cÑ!=±HÓ!=ŸcœcÐ=šcÐ=˜cÑ!=±HÓ!=Ó=Ð=rË   Ú
min_lengthc               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rJ  r   rd  ÚintrÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   4  s!   € ÷ 4ñ 4˜Sð 4°ð 4¸Tñ 4rË   c               óÜ   € \        V \        4      '       g   R# V P                  4       p\        V4      V8¬  ;'       d0    VP	                  4       \
        9  ;'       d    \        V4      '       * # )zIReturn True when a configured secret looks usable, not empty/placeholder.F)r+  rÄ   rÜ   r\  rÔ   Ú_PLACEHOLDER_SECRET_VALUESrc  )rJ  rd  Úcleaneds   &$ rÉ   Úhas_usable_secretrj  4  s\   € ä�eœS×!Ò!ÙØ�k‰k‹m€GÜ�‹L˜JÑ&÷ 3ð 3Ø—‘“Ô'AÑA÷3ð 3ä)¨'Ó2Ô2ð4rË   Ú
openrouterzdict[str, tuple]ÚKNOWN_PROVIDER_KEY_PREFIXESc               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   Úprovider_idrÄ   ÚvalrÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   G  s&   € ÷ Lñ L Sð L¨sð L°tñ LrË   c                óL   € VP                  \        P                  V R4      4      # )zqTrue when *val* starts with one of *provider_id*'s declared key prefixes (False when the
provider declares none).rÇ   )rY  rl  Úget)rn  ro  s   &&rÉ   Ú_matches_key_prefixrr  G  s!   € ð �>‰>Ô5×9Ñ9¸+ÀrÓJÓKÐKrË   c               ó    € V ^8„  d   QhRRRR/# ©rÂ   rJ  r   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   M  s   € ÷ Gñ G Sð G¨Tñ GrË   c                ó\   € \        R\        T ;'       g    R4      P                  4       4      # )zþTrue when *value* carries an OpenRouter key prefix. OPENAI_API_KEY is a legacy home for an
OpenRouter key, so only a value shaped like one may be read as an OpenRouter credential: a real
OpenAI key must never be auto-routed to, or sent to, openrouter.ai.rk  rÍ   )rr  rÄ   rÜ   ©rJ  s   &rÉ   Úlooks_like_openrouter_keyrw  M  s%   € ô ˜|¬S°·°¸"Ó-=×-CÑ-CÓ-EÓFÐFrË   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rÂ   rn  rÄ   rJ  r   ÚsourcerÅ   úOptional[str]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   T  s(   € ÷ ñ ¨ð °Sð À#ð È-ñ rË   c                ó  € \        T;'       g    R4      P                  4       p\        V4      '       g   R# \        P	                  V 4      pV'       d:   \        W4      '       g)   \        P                  RW RP                  V4      4       R# V# )zÚ*value* stripped when it is a usable, prefix-valid secret; None (after warning on a provable
prefix mismatch, so it never shadows a later credential source) otherwise. Providers without a
declared prefix are fail-open.rÍ   Nz´Ignoring %s for provider %r: value does not match the expected key prefix (%s). Falling back to the next credential source. Fix or remove the malformed key to silence this warning.z or )	rÄ   rÜ   rj  rl  rq  rr  ÚloggerÚwarningÚjoin)rn  rJ  ry  ro  Úprefixess   &&&  rÉ   Ú_usable_declared_secretr€  T  su   € ô ˆe�kˆk�rÓ
×
 Ñ
 Ó
"€CÜ˜S×!Ò!ÙÜ*×.Ñ.¨{Ó;€HßÔ+¨K×=Ò=Ü�‰ð@ð  §¡¨XÓ!6ô		8ñ
 Ø€JrË   c               ó    € V ^8„  d   QhRRRR/# ©rÂ   rn  rÄ   rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   f  s   € ÷ Wñ W cð W¨cñ WrË   c                óÈ  €  ^ RI Hp V! 4       ;'       g    / P                  R4      p\	        T\
        4      '       g   R# \        TP                  R4      ;'       g    R4      P                  4       P                  4       T 8w  d   R# \        TP                  R4      ;'       g    TP                  R4      ;'       g    R4      P                  4       #   \         d     R# i ; i)u1  ``model.key_env`` when config.yaml's main model targets *provider_id*, else ``""``.

The Desktop settings UI saves registry-provider keys as a credential pointer
(``model.key_env`` â†’ ``$HERMES_HOME/.env``) instead of the registry's canonical env var,
so credential resolution must consult it (#106336).
©Úload_configÚmodelrÍ   ÚproviderÚkey_envÚapi_key_env)	rE  r…  rq  rÖ   r+  rö   rÄ   rÜ   rÔ   )rn  r…  Ú	model_cfgs   &  rÉ   Ú_model_level_key_envr‹  f  s³   € ðÝ1Ù “]×(Ð( b×-Ñ-¨gÓ6ˆ	ô �i¤×&Ò&ÙÜ
ˆ9�=‰=˜Ó$×*Ð*¨Ó+×1Ñ1Ó3×9Ñ9Ó;¸{ÔJÙÜˆy�}‰}˜YÓ'×MÐM¨9¯=©=¸Ó+G×MÐMÈ2ÓN×TÑTÓVÐVøô ô Úðús   ‚C –C ÃC!Ã C!c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rn  rÄ   Úpconfigrâ   rÅ   útuple[str, str]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   y  s"   € ÷ ;ñ ;°#ð ;Àð ;ÐSbñ ;rË   c                óú  a€ V R8X  d+    ^ RI HpHp V! 4       w  rEV'       d   V! V4      w  rgWe3#  R# ^ RIHp	 \        V 4      p
V
'       d   \        W	! V
4      V
4      pV'       d   Wº3# VP                   F"  p\        W	! V4      V4      pV'       g   K  W¼3u # 	  RV  2p ^ RIHp V! V 4      pV'       dæ   VP                  4       '       dÐ   VP                  4       pVe   V.M. p VP!                  4        F\  oSf   K	  \"        ;QJ d    V3R	 lV 4       F  '       d   K   R
M	  RM! V3R	 lV 4       4      '       g   KK  VP%                  S4       K^  	  V F?  p\'        VRR4      ;'       g    \'        VRR4      p\        V VV4      pV'       g   K<  W½3u # 	  R#   \         d"   p\        P                  RT4        Rp?R# Rp?i\         d     R# i ; i  \         d     L�i ; i  \         d     R# i ; i)zDResolve an API-key provider's token and indicate where it came from.r  ©Úresolve_copilot_tokenÚget_copilot_api_tokenz#Copilot token validation failed: %sNrÍ   r;  zcredential_pool:©Ú	load_poolc              3  ó,   <"  € T F	  pSVJx € K  	  R # 5ir*  rÇ   )r,  rR  rì   s   & €rÉ   r.  Ú3_resolve_api_key_provider_secret.<locals>.<genexpr>©  s   øé € Ð0TÉÀA°¸aµËùs   ƒFTÚaccess_tokenÚruntime_api_key)rÍ   rÍ   )Úhermes_cli.copilot_authr‘  r’  Ú
ValueErrorr|  r}  rÖ   rE  r<  r‹  r€  rî   Úagent.credential_poolr”  Úhas_credentialsÚpeekÚentriesr]  ÚappendÚgetattr)rn  r�  r‘  r’  Útokenry  Ú	api_tokenÚ	_base_urlÚexcr<  rˆ  ro  Úenv_varÚpool_sourcer”  ÚpoolÚentryÚ
candidatesÚkeyrì   s   &&                 @rÉ   Ú _resolve_api_key_provider_secretr«  y  sø  ø€ à�iÔð		ß\Ù1Ó3‰MˆEßÙ'<¸UÓ'CÑ$�	Ø Ð(Ð(ð ð ˆõ >ô # ;Ó/€GßÜ% kÐ3NÈwÓ3WÐY`ÓaˆßØ�<Ðà×+Ô+ˆÜ% kÐ3NÈwÓ3WÐY`Óaˆß‰3ð �<Òñ ,ð % [ MÐ2€KðÝ3Ù˜Ó%ˆß�D×(Ñ(×*Ò*Ø—I‘I“KˆEØ$)Ò$5˜%™¸2ˆJðØ!Ÿ\™\ž^�EØÔ(¯S«SÔ0TÉÓ0T¯S¯SªSÔ0TÉÓ0T×-TÔ-TØ"×)Ñ)¨%Ö0ñ ,ó
 $�Ü˜e ^°RÓ8×aÐa¼GÀEÐK\Ð^`Ó<a�Ü-¨k¸3ÀÓL�ß‘3ØÐ+Ò+ñ	 $ð €Møôc ô 	GÜ�N‰NÐ@À#×FÐFð ˆûô ô 	ØØˆð	ûôL ô Ùðûô ô ØØ€Mðús�   Š%F Â!G+ Â7G+ ÃG+ Ã'G Ä 
G ÄG Ä"G ÅG ÅG+ Å0 G+ ÆG+ ÆG+ ÆGÆ)GÇGÇGÇGÇG(Ç%G+ Ç'G(Ç(G+ Ç+G:Ç9G:c               ó    € V ^8„  d   QhRRRR/# )rÂ   ÚerrorrÖ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ¹  s   € ÷ 7ñ 7 ið 7°Dñ 7rË   c                óŠ   € \        V \        4      ;'       d-    V P                  '       * ;'       d    V P                  \        8H  # )z¬True when an :class:`AuthError` is upstream rate-limiting / quota: transient, and
re-authenticating cannot fix it, so callers should say "retry later", not ``hermes auth``.)r+  r¾   Úrelogin_requiredÚcoder½   ©r­  s   &rÉ   Úis_rate_limited_auth_errorr²  ¹  s?   € ô �uœiÓ(÷ 6ð 6°×1GÑ1GÔ-G÷ 6ð 6Ø—
‘
Ô5Ñ5ð7rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   r­  rÖ   rÅ   rŽ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   À  s   € ÷ 0ñ 0 9ð 0°ñ 0rË   c                ó,   € \        V 4      '       d   R# R# )a  ``(log_phrase, user_phrase)`` for a primary-provider failure that triggers the fallback
chain. A 429/quota AuthError leaves the credentials valid; labelling it "auth failed" sends
operators hunting for an expired token (#117482), so it reads as quota at every surface.)zrate-limited (429)z Primary provider quota exhausted)zauth failedzPrimary auth failed)r²  r±  s   &rÉ   Úprimary_failure_wordingrµ  À  s   € ô " %×(Ò(ØGÐGØ/Ð/rË   Úsubscription_requiredzWNo active paid subscription found. Please purchase/activate a subscription, then retry.Úinsufficient_creditszESubscription credits are exhausted. Top up/renew credits, then retry.c               ó    € V ^8„  d   QhRRRR/# )rÂ   r­  rÖ   rÅ   rÄ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ò  s   € ÷ ñ ˜Yð ¨3ñ rË   c                ó¦  € \        V \        4      '       d   \        V 4      '       d   \        V 4      # V P                  '       d   ^ RIHp V  RV! 4        R2# V P                  \        9   dF   V P                  R8X  d   \        V 4      # \        P                  V P                  4      pV'       d   V# V P                  R8X  d   V  R2# \        V 4      # )z2Map auth failures to concise user-facing guidance.)Úprofile_cli_selectorz Run `hermes zmodel` to re-authenticate.rü   Útemporarily_unavailablez Please retry in a few seconds.)r+  r¾   r²  rÄ   r¯  Úhermes_constantsrº  r°  Ú_ENTITLEMENT_ERROR_CODESr‡  rB   Ú_GENERIC_ENTITLEMENT_MESSAGESrq  )r­  rº  Úgenerics   &  rÉ   Úformat_auth_errorrÀ  Ò  s±   € ä�eœY×'Ò'Ô+EÀe×+LÒ+Lä�5‹zÐØ××Ðå9à�˜Ñ&:Ó&<Ð%=Ð=WÐXÐXØ‡z�zÔ-Ô-Ø�>‰>˜VÔ#Ü6°uÓ=Ð=Ü/×3Ñ3°E·J±JÓ?ˆßØˆNØ‡z�zÐ.Ô.Ø�Ð7Ð8Ð8Üˆu‹:ÐrË   c               ó    € V ^8„  d   QhRRRR/# rt  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ç  s   € ÷ :ñ :˜ð : ñ :rË   c                ód   € \        V \        4      ;'       d    \        V P                  4       4      # r*  )r+  rÄ   rÆ   rÜ   rv  s   &rÉ   Ú_nonempty_strrÃ  ç  s"   € Ü�eœSÓ!×9Ð9¤d¨5¯;©;«=Ó&9Ð9rË   c               ó   € V ^8„  d   QhRR/# ©rÂ   rÅ   r   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   í  s   € ÷ 
ñ 
˜ñ 
rË   c                 óö   € \        4       R ,          p \        P                  P                  R4      '       dC   \	        V \
        P                  ! 4       R,          R ,          4      '       d   \        RV  R24      hV # )ú	auth.jsonÚPYTEST_CURRENT_TESTú.hermesz8Refusing to touch real user auth store during test run: zq. Set HERMES_HOME to a tmp_path in your test fixture, or run via scripts/run_tests.sh for hermetic CI-parity env.)r1  ÚosÚenvironrq  Ú
_same_pathr   ÚhomeÚRuntimeError©rÝ   s    rÉ   Ú_auth_file_pathrÐ  í  sl   € ÜÓ˜{Õ*€Dô 	�
‰
�‰Ð,×-Ò-Ü˜4¤§¢£¨yÕ!8¸;Õ!F×GÒGÜØFÀtÀfð MCð CóDð 	Dð €KrË   c               ó   € V ^8„  d   QhRR/# )rÂ   rÅ   úOptional[Path]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ú  s   € ÷ 	]ñ 	] ñ 	]rË   c                 óŒ   €  ^ RI Hp  V ! 4       p\        \	        4       T4      '       d   R# TR,          #   \         d     R# i ; i)zµGlobal-root auth.json in profile mode; None when profile and global root are the same dir.

Read-only fallback path, so no pytest seat belt here (it lives on ``_auth_file_path()``).)Úget_default_hermes_rootNrÇ  )r¼  rÔ  rÖ   rÌ  r1  )rÔ  Úglobal_roots     rÉ   Ú_global_auth_file_pathrÖ  ú  sH   € ðÝ<Ù-Ó/ˆô œoÓ/°×=Ò=ˆ4Ð\À;ÐQ\ÕC\Ð\øô ô Úðús   ‚4 ´AÁAc               ó   € V ^8„  d   QhRR/# ©rÂ   rÅ   rë   rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s   € ÷ ñ  ñ rË   c                 óž  € \        4       p V e   V P                  4       '       g   Rs/ #  \        V P	                  RR7      4      \        V P                  4       4      3p\        pVe   Ve   VR,          V8X  d
   V^,          # \        P                  P                  R4      '       dÕ   \        P                  P                  R4      '       d°   \        \        P                  R,          4      R,          R,          p \        P                  P                  \        P                  P                  V 4      4      \        P                  P                  \        P                  P                  V4      4      8X  d   Rs/ #   \        V 4      pTe   . TOTN5sT#   \         d    Rp ELGi ; i  \         d     L:i ; i  \         d    Rs/ u # i ; i)	u£   Load the global-root auth store (read-only fallback, mtime-memoised); ``{}`` when absent or
unreadable â€” a malformed global store must never break profile reads.NF©Ústrict:NrÂ   NrÈ  ÚHOMErÉ  rÇ  )rÖ  ÚexistsÚ_global_auth_store_cacherÄ   Úresolver   ÚstatrÖ   rÊ  rË  rq  r   rÝ   ÚnormcaseÚabspathÚ_load_auth_store)Úglobal_pathÚ	cache_keyÚcachedÚ	real_rootÚstores        rÉ   Ú_load_global_auth_storeré    s•  € ô )Ó*€KØÒ +×"4Ñ"4×"6Ò"6Ø#'Ð Øˆ	ðä�×#Ñ#¨5Ð#Ó1Ó2´NÀ;×CSÑCSÓCUÓ4VðFXˆ	ô &€FØÒ Ò!3¸¸r½
ÀiÔ8OØ�a�yÐÜ	‡z�z‡~�~Ð+×,Ò,´·±·±À×1GÒ1GÜœŸ™ FÕ+Ó,¨yÕ8¸;ÕFˆ	ð	Ü�w‰w×Ñ¤§¡§¡°Ó <Ó=ÄÇÁ×AQÑAQÔRT×RYÑRY×RaÑRaÐbkÓRlÓAmÔmØ+/Ð(Ø�	ð nð
Ü  Ó-ˆð ÒØ#6 YÐ#6°Ñ#6Ð Ø€Løô) ô Ø‹	ðûô ô 	Ùð	ûô ô Ø#'Ð ØŠ	ðús6   ª4F Ã<A>F) Å=F: ÆF&Æ%F&Æ)F7Æ6F7Æ:GÇGzdict[str, threading.local]Ú_auth_target_lock_holdersc               ó$   € V ^8„  d   QhRRRRRR/# ©rÂ   Úleftr   ÚrightrÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ,  s!   € ÷ ñ �Tð  $ð ¨4ñ rË   c                óx   €  V P                  R R7      VP                  R R7      8H  #   \         d    Y8H  u # i ; i)FrÚ  )rß  rÖ   ©rí  rî  s   &&rÉ   rÌ  rÌ  ,  s?   € ðØ�|‰| 5ˆ|Ó)¨U¯]©]À%¨]Ó-HÑHÐHøÜô Ø‰}Òðús   ‚$' §9¸9c               ó$   € V ^8„  d   QhRRRRRR/# rì  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   3  s!   € ÷ ñ ˜dð ¨4ð °Dñ rË   c                óp   € \        W4      '       d   R#  V P                  V4      #   \         d     R# i ; i)a   True when two auth paths name ONE store rather than two copies.
``_same_path`` resolves symlinks and ``..``; ``samefile`` adds hardlinks and bind-mounts
(same inode under two resolved names). Used by the forked-grant heal: a shared store has
no "other side" to consolidate.

See #101356.
TF)rÌ  ÚsamefileÚOSErrorrð  s   &&rÉ   Ú_is_same_auth_storerõ  3  s8   € ô �$×ÒÙðØ�}‰}˜UÓ#Ð#øÜô Úðús   •& ¦5´5c               ó    € V ^8„  d   QhRRRR/# )rÂ   rÝ   r   rÅ   rÄ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   C  s   € ÷ ñ ˜ð  ñ rË   c                ór   €  \        V P                  RR7      4      #   \         d    \        T 4      u # i ; i)zWCanonical string for *path* (resolved when possible) used as a cache / lock-holder key.FrÚ  )rÄ   rß  rÖ   rÏ  s   &rÉ   Ú_resolved_keyrø  C  s6   € ðÜ�4—<‘< u�<Ó-Ó.Ð.øÜô Ü�4‹yÒðús   ‚ �6µ6c               ó    € V ^8„  d   QhRRRR/# )rÂ   Útarget_pathr   rÅ   úthreading.localrÇ   )rÈ   s   "rÉ   rÊ   rÊ   K  s   € ÷ cñ c tð c°ñ crË   c                óÀ   € \         ;_uu_ 4        \        P                  \        V 4      \        P
                  ! 4       4      uuRRR4       #   + '       g   i     R# ; i)zCReturn a reentrancy tracker keyed to one canonical auth-store path.N)Ú_auth_target_lock_holders_guardrê  Ú
setdefaultrø  Ú	threadingÚlocal©rú  s   &rÉ   Ú_auth_lock_holder_forr  K  s6   € ç	(Ö	(Ü(×3Ñ3´MÀ+Ó4NÔPY×P_ÒP_ÓPaÓb÷ 
)×	(×	(Ó	(ús   �2AÁA	c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   Ú	lock_filer   ÚacquirerÆ   rÅ   ÚNonerÇ   )rÈ   s   "rÉ   rÊ   rÊ   Q  s&   € ÷ _ñ _˜Cð _¨$ð _°4ñ _rË   c                óœ  € \         '       dc   \         P                  ! V P                  4       V'       d&   \         P                  \         P                  ,          M\         P
                  4       R# V P                  ^ 4       \        P                  ! V P                  4       V'       d   \        P                  M\        P                  ^4       R# )zcNon-blocking exclusive flock (fcntl) or 1-byte msvcrt lock at offset 0; ``acquire=False`` releases.N)ÚfcntlÚflockÚfilenoÚLOCK_EXÚLOCK_NBÚLOCK_UNÚseekÚmsvcrtÚlockingÚLK_NBLCKÚLK_UNLCK)r  r  s   &&rÉ   Ú_kernel_lockr  Q  sh   € çƒuÜ�Š�I×$Ñ$Ó&Ï7¬¯©¼¿¹Ö)FÔX]×XeÑXeÖfà�‰�qÔÜ�Š�y×'Ñ'Ó)¿g¬6¯?ª?Ì6Ï?É?Ð\]Ö^rË   c              #  ó0   "  € T F  qf   K  Vx € K  	  R # 5ir*  rÇ   )r,  r°  s   & rÉ   r.  r.  ^  s   é € ð $hÙRˆT‡D‚DÓRùs   ‚Œ
ÚEDEADLKc               ó    € V ^8„  d   QhRRRR/# )rÂ   r¤  rô  rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   b  s   € ÷ 0ñ 0˜Wð 0¨ñ 0rË   c                óX   € \        V \        4      '       d   R # V P                  \        9   # )T)r+  ÚBlockingIOErrorÚerrnoÚ_LOCK_CONTENTION_ERRNOS)r¤  s   &rÉ   Ú_is_lock_contentionr  b  s"   € Ü�#”×'Ò'ÙØ�9‰9Ô/Ñ/Ð/rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   Ú	lock_pathr   rÅ   rÄ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   h  s   € ÷ Iñ I ð I¨#ñ IrË   c                óŒ  €  V P                  RRR7      P                  4       ^ ,          p\        V4      pT^ 8:  g   T\        P                  ! 4       8X  d   R# \        P                  R8X  d    \        P                  ! T^ 4       RT R2#   \        \        \
        3 d     R# i ; i  \         d     R# \         d     L=i ; i)u
  Live-holder hint from the pid a holder stamps into the lock file; empty when there is none.

Holders stamp their pid on acquire and clear it on release, so a leftover pid from a dead
process is filtered by a liveness probe â€” stay silent instead of blaming a ghost.ú	utf-8-sigr^  ©ÚencodingÚerrorsrÍ   Úposixzanother hermes process (pid z) probably still holds it)Ú	read_textÚsplitrf  rô  rš  Ú
IndexErrorrÊ  Úgetpidrä   ÚkillÚProcessLookupError)r  Úfirst_tokenÚpids   &  rÉ   Ú_lock_holder_hintr,  h  s·   € ð
Ø×)Ñ)°;ÀyÐ)ÓQ×WÑWÓYÐZ[Õ\ˆÜ�+Óˆð ˆa„x�3œ"Ÿ)š)›+Ô%ÙÜ	‡w�w�'Ôð	Ü�GŠG�C˜ŒOð *¨#¨Ð.GÐHÐHøô ”Z¤Ð,ô Úðûô "ô 	ÚÜô 	Ùð	ús/   ‚3B Á.B( ÂB%Â$B%Â(CÂ6CÂ?CÃCc               ó    € V ^8„  d   QhRRRR/# ©rÂ   r  r   rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s   € ÷ ñ  cð ¨dñ rË   c                ó¼   €  V P                  ^ 4       V P                  \        P                  ! 4        R24       V P	                  4        R#   \
         d     R# i ; i)zKBest-effort pid stamp so a timing-out waiter can name the holder (#124533).Ú
N)ÚtruncateÚwriterÊ  r'  Úflushrô  ©r  s   &rÉ   Ú_stamp_lock_holder_pidr5    sJ   € ðØ×Ñ˜1ÔØ�‰œ2Ÿ9š9›;˜- rÐ*Ô+Ø�‰ÖøÜô Úðús   ‚AA ÁAÁAc               ó    € V ^8„  d   QhRRRR/# r.  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ‰  s   € ÷ ñ ¨cð °dñ rË   c                ó¨   €  V P                  ^ 4       \        '       d   V P                  R4       V P                  4        R#   \         d     R# i ; i)é    rU  N)r1  r  r2  r3  rô  r4  s   &rÉ   Ú_clear_stamped_lock_holder_pidr9  ‰  sB   € ðØ×Ñ˜1Ôß‹6Ø�O‰O˜CÔ Ø�‰ÖøÜô Úðús   ‚A Ÿ!A ÁAÁAc               ó(   € V ^8„  d   QhRRRRRRRR/# )	rÂ   r  r   Úholderrû  Útimeout_secondsÚfloatÚtimeout_messagerÄ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ”  s,   € ÷ 9ñ 9Øð9Ø,ð9Ø?Dð9ØWZñ9rË   c           	   #  ót  "  € \        VR^ 4      ^ 8”  d:   V;P                  ^,          un         Rx € V;P                  ^,          un        R# V P                  P                  RRR7       \	        4       ;_uu_ 4       pRp\
        f	   \        e»   \        '       dJ   V P                  4       '       d    V P                  4       P                  ^ 8X  d    V P                  RRR7       TP                  T P                  \        '       d   RMR	RR7      4      p\        P                   ! 4       \#        R
V4      ,           p  \%        VR4        ^Vn         Ve   \1        V4       Rx € ^ Vn        Ve   \3        V4        \%        VR4       M RRR4       R#   T;P                  ^,          un        i ; i  \        \        3 d     Lài ; i  \&        \        \        3 dx   p\)        T4      '       g   h \        P                   ! 4       T8¼  d*   \+        T 4      p\-        T'       d   T RT 24      hT4      h\        P.                  ! R4        Rp?EK  Rp?ii ; i  \         d     LÜi ; i  ^ Tn        Te+   \3        T4        \%        TR4       i   \         d     i i ; ii ; i  + '       g   i     R# ; i5i)a<  Cross-process advisory flock helper, reentrant per-thread via ``holder.depth``.

Falls back to a depth-only guard when neither ``fcntl`` nor ``msvcrt`` is available. Callers
supply their own ``threading.local`` so independent locks (profile store vs global root vs the
shared Nous store) track reentrancy separately.ÚdepthNT©ÚparentsÚexist_okrU  zutf-8©r!  zr+za+g      ð?z; gš™™™™™©?F)r   r@  ÚparentÚmkdirr   r  r  rÝ  rà  Úst_sizeÚ
write_textrô  ÚPermissionErrorÚenter_contextÚopenÚtimeÚ	monotonicÚmaxr  r  r  r,  ÚTimeoutErrorÚsleepr5  r9  )	r  r;  r<  r>  Ústackr  Údeadliner¤  Úhints	   &&&&     rÉ   Ú
_file_lockrT  “  sM  é € ô ˆv�w Ó" QÔ&Ø�Š˜Õ�ð	Ûà�LŠL˜AÕ�LÙà×Ñ×Ñ 4°$ÐÔ7Ü	�Œ˜Øˆ	ÜÒ¤Ò 2÷
 ‹v˜y×/Ñ/×1Ò1°Y·^±^Ó5E×5MÑ5MÐQRÔ5RðØ×(Ñ(¨°wÐ(Ô?ð ×+Ñ+¨I¯N©NÇ6Ã6¹4ÈtÐ^e¨NÓ,fÓgˆIÜ—~’~Ó'¬#¨c°?Ó*CÕCˆHØð%Ü  ¨DÔ1Øð ˆŒð	ØÒ$Ü& yÔ1ÛàˆFŒLØÒ$Ü.¨yÔ9ðÜ  ¨EÕ2ð %÷I 
‰øð	 �LŠL˜AÕŽLûô  ¤Ð1ô Ùðûô (¬´/ÐBô 	%Ü.¨s×3Ò3ð Ü—~’~Ó'¨8Ô3Ü0°Ó;˜Ü*Ï4¨oÐ->¸bÀÀÐ+GÓeÐeÐUdÓeÐeÜ—J’J˜t×$Ó$ûð	%ûô, ô Ùðûð ˆFŒLØÒ$Ü.¨yÔ9ðÜ  ¨EÕ2øÜô Ùðúð	 %ú÷I 
�ˆüsõ   ‚,J8¯F ³A
J8Á=J$ÂJ$Â2J$ÃF2Ã%!J$Ä5J$Ä=G	Å	J$ÅI*Å%J$Å<IÆJ$Æ

J8ÆF/Æ/J8Æ2GÇJ$ÇGÇJ$Ç	IÇA+IÉ
J$ÉIÉJ$ÉI'É$J$É&I'É'J$É*J!ÊJÊJ!ÊJÊJ!ÊJÊJ!Ê!J$Ê$J5	Ê/	J8rú  c               ó    € V ^8„  d   QhRRRR/# )rÂ   r<  r=  rú  rÒ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ñ  s   € ÷ ñ ØðØHVñrË   c             #  óØ   "  € Ve   TM	\        4       pVP                  R4      p\        V\        V4      V RV R24      ;_uu_ 4        Rx € RRR4       R#   + '       g   i     R# ; i5i)a]  Cross-process advisory lock for one auth.json read/write transaction.

``target_path`` is required for profile-to-global write-throughs: each path has its own
reentrancy tracker and kernel lock. Lock ordering invariant: ``_auth_store_lock`` FIRST (outer),
``_nous_shared_store_lock`` SECOND (inner), else deadlock against a concurrent shared import.Nz.lockz'Timed out waiting for auth store lock (Ú))rÐ  Úwith_suffixrT  r  )r<  rú  Ú	auth_pathr  s   &$  rÉ   Ú_auth_store_lockrZ  Ð  sk   é € ð  +Ò6‘¼OÓ<M€IØ×%Ñ% gÓ.€IÜ	ØÔ(¨Ó3°_Ø
1°)°¸AÐ>÷
@õ 
@ó 	÷
@÷ 
@÷ 
@ò 
@üs   ‚AA*ÁAÁ
A*ÁA'	Á!	A*c               ó   € V ^8„  d   QhRR/# rØ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   à  s   € ÷ <ñ <˜>ñ <rË   c                 ó   € R \         R/ /# )ÚversionÚ	providers)r˜   rÇ   rË   rÉ   Ú_empty_auth_storer_  à  s   € ØÔ)¨;¸Ð;Ð;rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   Ú	auth_filerÒ  rÅ   rë   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ä  s   € ÷ -ñ - ð -¸.ñ -rË   c                óˆ  € T ;'       g    \        4       p V P                  4       '       g   \        4       #  \        P                  ! V P                  R R7      4      p\        T\        4      '       d–   \        TP!                  R4      \        4      '       g&   \        TP!                  R4      \        4      '       dL   TP#                  R/ 4       \        TP!                  R4      \        4      '       d   \%        TR,          4       T# \        T\        4      '       da   \        TP!                  R4      \        4      '       d<   TR,          pRT9   d   RTR,          /M/ p/ \        4       CRTRT'       d   R/C# R/C# \        4       #   \         d    \        P                  RT RR7       h \         d�   pT P                  R4      p \        P                  ! Y4       RpM+  \         d    Rp\        P                  RTRR7        Mi ; i\        P                  RYT'       d   R	MR
T4       \        4       u Rp?# Rp?ii ; i)r  rD  zbauth: could not read %s, leaving the store on disk untouched rather than degrading to an empty oneT)Úexc_infoz.json.corruptFz:auth: could not preserve a copy of the corrupt store at %sz?auth: failed to parse %s (%s), starting with empty store. %s %szCorrupt file preserved atz A copy could NOT be preserved atNr^  Úcredential_poolÚsystemsÚnous_portalrü   Úactive_provider)rÐ  rÝ  r_  ÚjsonÚloadsr$  rô  r|  r}  rÖ   rX  ÚshutilÚcopy2Údebugr+  rö   rq  rþ  rF   )ra  Úrawr¤  Úcorrupt_pathÚ	preservedre  r^  s   &      rÉ   rã  rã  ä  s   € Ø×.Ð.œ_Ó.€IØ×Ñ×ÒÜ Ó"Ð"ð#Ü�jŠj˜×,Ñ,°kÐ,ÓBÓCˆô8 �#”t×ÒÜ�3—7‘7˜;Ó'¬×.Ò.´*¸S¿W¹WÐEVÓ=WÔY]×2^Ò2^Ø�‰�{ BÔ'Ü�c—g‘g˜kÓ*¬D×1Ò1Ü*¨3¨{Õ+;Ô<Øˆ
ä�#”t×Ò¤¨C¯G©G°IÓ,>Ä×!EÒ!EØ�i•.ˆØ8EÈÔ8P�V˜W ]Õ3Ñ4ÐVXˆ	ðBÔ#Ó%ð B {°IØ!¯Y 6ñBð 	BØ<@ñBð 	BäÓÐøôO ô ô 	�‰ð4à ð 	ô 	&ð 	Üô #ð !×,Ñ,¨_Ó=ˆð	(Ü�LŠL˜Ô1Ø‰IøÜô 	(ØˆIÜ�L‰LÐUÐWcØ"&ð ö (ð	(úô 	�‰ØMØß+4Ñ'Ð:\Øô		ô
 !Ó"Õ"ûð!#úsG   ¶&F Æ,IÆ4IÆ5H<ÇG ÇH<Ç %HÈH<ÈHÈ.H<È6IÈ<IÚ	fsync_dirFc          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
rÂ   Útargetr   Údatar   rp  rÆ   Údump_kwargsrÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s8   € ÷ Tñ T˜tð T¨3ð T¸dð TÐ[^ð TÐcgñ TrË   c               ól   € ^ RI Hp V! V P                  4       \        V 4       \	        W3RRRV/VB  R# )z¼0600 credential JSON under a 0700 parent (``secure_parent_dir`` refuses ``/``, top-level dirs
and the install tree). ``atomic_json_write`` creates the temp file 0600 before any byte lands.)Úmkdir_under_hermes_homeÚmodei€  rp  N)r¼  rv  rE  r   r   )rr  rs  rp  rt  rv  s   &&$, rÉ   Ú_save_private_jsonrx    s2   € õ 9Ù˜FŸM™MÔ*Ü�fÔÜ�fÑS¨ÐS¸)ÐSÀ{ÔSrË   c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   Ú
auth_storerë   rú  rÒ  rÅ   r   rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s"   € ÷ ñ  ð ¸nð ÐX\ñ rË   c                ó´   € Ve   TM	\        4       p\        V R&   \        P                  ! \        4      P                  4       V R&   \        W RR7       Ve   RsV# )z»Atomically persist *auth_store* (0o600, parent tightened to 0o700) to the active store, or to
an explicit *target_path* (e.g. the global-root write-through for rotating xAI OAuth grants).Nr]  Ú
updated_atT)rp  )rÐ  r˜   r	   Únowr   Ú	isoformatrx  rÞ  )rz  rú  ra  s   && rÉ   Ú_save_auth_storer    sW   € ð  +Ò6‘¼OÓ<M€IÜ.€JˆyÑÜ'Ÿ|š|¬CÓ0×:Ñ:Ó<€Jˆ|ÑÜ�y¸Õ=ØÒð $(Ð ØÐrË   c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rz  rë   rª  rÄ   rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ,  s!   € ÷ ñ ˜~ð °Cð ¸Nñ rË   c                ó`   € V P                  V4      p\        V\        4      '       g   / ;q V&   V# )zRReturn ``auth_store[key]`` as a dict, replacing a missing/non-dict value in place.©rq  r+  rö   )rz  rª  Úsections   && rÉ   Ú_store_sectionr„  ,  s.   € à�n‰n˜SÓ!€GÜ�gœt×$Ò$Ø$&Ð&ˆ˜S‘/Ø€NrË   c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rè  rë   rn  rÄ   rÅ   úOptional[dict[str, Any]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   4  s"   € ÷ <ñ <˜nð <¸3ð <ÐC[ñ <rË   c                óÐ   € V '       d   V P                  R4      MRp\        V\        4      '       d   VP                  V4      MRp\        V\        4      '       d   \        V4      # R# )zQShallow copy of ``store["providers"][provider_id]`` when it is a dict, else None.r^  Nr‚  )rè  rn  r^  Ústates   &&  rÉ   Ú_provider_state_inr‰  4  sK   € ç*/�—	‘	˜+Ô&°T€IÜ*4°YÄ×*EÒ*EˆI�M‰M˜+Ô&È4€EÜ$ U¬D×1Ò1Œ4�‹;Ð;°tÐ;rË   c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rz  rë   rn  rÄ   rÅ   z/tuple[Optional[dict[str, Any]], Optional[Path]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ;  s)   € ÷ bñ bØðbØ-0ðbà4ñbrË   c                ó„   € \        W4      pVe   V\        4       3# \        \        4       V4      pVe   V\        4       3# R# )zÔProvider state plus the auth.json path it came from (profile first, then the global root).

Refresh paths that rotate single-use OAuth refresh tokens must write the updated chain back to
the same store they read.©NN)r‰  rÐ  ré  rÖ  )rz  rn  rˆ  Úglobal_states   &&  rÉ   Ú _load_provider_state_with_sourcerŽ  ;  sL   € ô ˜zÓ7€EØÒØ”oÓ'Ð'Ð'Ü%Ô&=Ó&?ÀÓM€LØ7CÒ7OˆLÔ0Ó2Ð3ÐaÐUaÐarË   c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rz  rë   rn  rÄ   rÅ   r†  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   I  s'   € ÷ Hñ H ^ð HÀ#ð HÐJbñ HrË   c                ó&   € \        W4      ^ ,          # )z¸Provider state; in profile mode falls back to the global-root ``auth.json`` per provider (same
shadowing as ``read_credential_pool``), so profile workers see globally-authed providers.)rŽ  )rz  rn  s   &&rÉ   Ú_load_provider_stater‘  I  s   € ô ,¨JÓDÀQÕGÐGrË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   rn  rÄ   r<  r=  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   P  s    € ÷ jñ jØðjØ+0ñjrË   c           
   #  óŽ  "  € \        V4      ;_uu_ 4        \        4       p\        W 4      w  r4Ve   \        V\	        4       4      '       d   W#V3x €  RRR4       R# \        WR7      ;_uu_ 4        V\        \        V4      V 4      V3x € RRR4       RRR4       R#   + '       g   i     L; i  + '       g   i     R# ; i5i)ac  Lock the active auth store and any global fallback source, in that order.

Re-reading the source after its lock is acquired prevents stale refreshes and whole-file lost
updates without inverting the documented auth -> shared lock order. ``timeout_seconds`` applies
to BOTH locks: a transaction that spans a network call must let waiters outlive that call.Nr  )rZ  rã  rŽ  rÌ  rÐ  r‰  )rn  r<  rz  rˆ  Úsource_paths   &&   rÉ   Ú_provider_state_transactionr•  O  sŸ   é € ô 
˜/×	*Õ	*Ü%Ó'ˆ
Ü=¸jÓVÑˆØÒ¤*¨[¼/Ó:K×"LÒ"LØ [Ð0Ò0Ø÷ 
+Ñ	*ô ˜o×GÖGØÔ0Ô1AÀ+Ó1NÐP[Ó\Ð^iÐiÒi÷ H÷ 
+Ñ	*÷ H×Gú÷ 
+×	*Ð	*üs@   ‚C–=B1Á
CÁB1Á1B	ÂB1Â
CÂB.Â)B1Â1C	Â<	CÚ
set_activeTc          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
rÂ   rz  rë   rn  rÄ   rˆ  r–  rÆ   rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   a  s5   € ÷ 4ñ 4 nð 4À3ð 4È~ð 4Ðnrð 4ð  Cñ 4rË   c               óX   € \        WV4       V\        V R 4      V&   V'       d   WR&   R# R# )r^  rg  N)r�   r„  )rz  rn  rˆ  r–  s   &&&$rÉ   Ú_store_provider_stater™  a  s.   € Ü�Z¨eÔ4Ø;@„N�:˜{Ó+¨KÑ8ßØ(3Ð$Ó%ñ rË   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rÂ   rz  rë   rn  rÄ   rˆ  rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   h  s/   € ÷ Kñ K ^ð KÀ#ð KÈnð KÐaeñ KrË   c                ó"   € \        WVRR7       R# )zMWrite *state* under ``providers`` and make *provider_id* the active provider.T©r–  N)r™  )rz  rn  rˆ  s   &&&rÉ   Ú_save_provider_stater�  h  s   € ä˜*°5ÀT×JrË   c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rn  rÄ   rˆ  rë   rÅ   r   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   m  s!   € ÷ ,ñ ,¨Sð ,¸ð ,ÈDñ ,rË   c                ó¦   € \        4       ;_uu_ 4        \        4       p\        W V4       \        V4      uuRRR4       #   + '       g   i     R# ; i)zTLock, load, write *state* as the active provider, save. Returns the auth store path.N)rZ  rã  r�  r  )rn  rˆ  rz  s   && rÉ   Ú_save_active_provider_stater   m  s4   € ä	×	Õ	Ü%Ó'ˆ
Ü˜Z°eÔ<Ü 
Ó+÷ 
×	×	Ó	ús	   “!?¿A	c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
rÂ   rn  rÄ   rˆ  rë   rú  r   r–  rÆ   rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   u  s;   € ÷ Eñ EØðEØ+ðEØ:>ðEØOSðEà	ñErË   c          	     óÄ   € \        VR7      ;_uu_ 4        \        V4      p\        W@\        V4      VR7       \	        WBR7      uuRRR4       #   + '       g   i     R# ; i)zFMerge one provider into a specific auth store under that store's lock.r  rœ  N)rZ  rã  r™  rö   r  )rn  rˆ  rú  r–  rz  s   &&&$ rÉ   Ú _persist_provider_state_to_storer£  u  s@   € ô 
 k×	2Ö	2Ü% kÓ2ˆ
Ü˜j´t¸E³{ÈzÕZÜ 
ÔD÷ 
3×	2×	2Ó	2ús   •.AÁA	c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
rÂ   rz  rë   rn  rÄ   rˆ  r”  rÒ  rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s;   € ÷ \ñ \Øð\Ø-0ð\Ø9Gð\ØVdð\à	ñ\rË   c                ó”   € Ve   \        V\        4       4      '       d   \        WVRR7       \        V 4       R# \	        WVRR7       R# )a4  Persist provider state back to the auth store it was read from.

A token refresh rewrites credentials, not the user's choice of provider: ``active_provider`` is
left as it is (a Nous free-tier identity refreshed for a connector call must not become the
inference provider of an install that has its own key).NFrœ  )rÌ  rÐ  r™  r  r£  )rz  rn  rˆ  r”  s   &&&&rÉ   Ú_save_provider_state_to_sourcer¦    s:   € ð Òœj¨´oÓ6G×HÒHÜ˜j°uÈÕOÜ˜Ö$ä(¨¸[ÐUZ×[rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   rn  rÄ   rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ž  s   € ÷ )ñ )¨sð )°tñ )rË   c                óô   € \        4       ;_uu_ 4        \        4       pVP                  R4      ;'       g    RP                  4       '       g   WR&   \	        V4       RRR4       R#   + '       g   i     R# ; i)zàSet ``active_provider`` only when none is set yet: the first ``hermes auth add`` credential must
make its provider active (else setup reports "No inference provider configured"); later adds
leave the user's choice untouched.rg  rÍ   N)rZ  rã  rq  rÜ   r  )rn  rz  s   & rÉ   Úmark_provider_active_if_unsetr©  Ž  sV   € ô 
×	Õ	Ü%Ó'ˆ
Ø—‘Ð0Ó1×7Ð7°R×>Ñ>×@Ò@Ø,7Ð(Ñ)Ü˜ZÔ(÷	 
×	×	Ò	ús   “9A&ÁA&Á&A7	c               ó    € V ^8„  d   QhRRRR/# ©rÂ   rn  rÄ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ™  s   € ÷ 4ñ 4¨ð 4°ñ 4rË   c                ól   € T ;'       g    R P                  4       P                  4       p\        V4      RJ# rC  )rÜ   rÔ   Ú_registry_lookup©rn  Ú
normalizeds   & rÉ   Úis_known_auth_providerr°  ™  s1   € Ø×#Ð# ×*Ñ*Ó,×2Ñ2Ó4€JÜ˜JÓ'¨tÐ3Ð3rË   c               ó    € V ^8„  d   QhRRRR/# r‚  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ž  s   € ÷ ñ °ð ¸ñ rË   c                óš   € T ;'       g    R P                  4       P                  4       pV\        9   d   \        V,          P                  # V # ©rÍ   )rÜ   rÔ   r/  rä   r®  s   & rÉ   Úget_auth_provider_display_namer´  ž  sA   € Ø×#Ð# ×*Ñ*Ó,×2Ñ2Ó4€JØÔ&Ô&Ü  Õ,×1Ñ1Ð1ØÐrË   c               ó    € V ^8„  d   QhRRRR/# r«  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ¥  s   € ÷ ñ ¨cð °dñ rË   c                óæ   € T ;'       g    RP                  4       P                  4       pV'       g   R# VR9   g   VP                  R4      '       d   R#  \        V4       R#   \         d     R# i ; i)zÄWhether runtime resolution recognizes a provider identity (a capability check, not a credential
check): ``resolve_provider`` normalization plus the special runtime identities outside the registry.rÍ   Fúcustom:T>   ÚmoaÚautoÚcustomrk  )rÜ   rÔ   rY  Úresolve_providerr¾   r®  s   & rÉ   Úis_runtime_provider_routabler¼  ¥  sl   € ð ×#Ð# ×*Ñ*Ó,×2Ñ2Ó4€JßÙØÐ<Ô<À
×@UÑ@UÐV_×@`Ò@`ÙðÜ˜Ô$ñ øô ô Úðús   ÁA! Á!A0Á/A0c               ó    € V ^8„  d   QhRRRR/# ©rÂ   rn  rz  rÅ   rë   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ´  s   € ÷ Lñ L mð L¸~ñ LrË   c                óº  € \        4       P                  R4      p\        V\        4      '       d   TM/ p\	        4       P                  R4      p\        V\        4      '       d   TM/ pV f…   \        V4      pVP                  4        Fc  w  rEVP                  V4      p\        V\        4      '       d	   V'       g   K6  \        V\        4      '       d   V'       d   KV  \        V4      W4&   Ke  	  V# VP                  V 4      p\        V\        4      '       d   V'       d   \        V4      # VP                  V 4      p\        V\        4      '       d   \        V4      # . # )zûReturn the persisted credential pool, or one provider slice.

In profile mode the global-root ``auth.json`` is a read-only fallback applied per provider ONLY
when the profile has zero entries for it (``hermes auth add`` in the profile shadows global).rd  )rã  rq  r+  rö   ré  ÚitemsÚlist)	rn  r§  Úglobal_poolÚmergedÚgp_keyÚ
gp_entriesÚexistingÚprovider_entriesÚglobal_entriess	   &        rÉ   Úread_credential_poolrÉ  ´  s  € ô
 Ó×!Ñ!Ð"3Ó4€DÜ˜d¤D×)Ò)‰4¨r€DÜ)Ó+×/Ñ/Ð0AÓB€KÜ!+¨K¼×!>Ò!>‘+ÀB€KàÒÜ�d“ˆØ"-×"3Ñ"3Ö"5ÑˆFØ—z‘z &Ó)ˆHÜ˜z¬4×0Ò0·ZÙÜ˜x¬×.Ò.·8±8Ü!% jÓ!1�“ñ #6ð ˆà—x‘x Ó,ÐÜÐ"¤D×)Ò)×.>ÜÐ$Ó%Ð%Ø —_‘_ [Ó1€NÜ#-¨n¼d×#CÒ#CŒ4�ÓÐKÈÐKrË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   Úrowr   rÅ   ztuple[Any, Any]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ü  s   € ÷ =ñ = ð =¨ñ =rË   c                óv   € \        V \        4      '       g   R# V P                  R4      V P                  R4      3# )Nr—  Úrefresh_tokenrŒ  ©r+  rö   rq  )rË  s   &rÉ   Ú_credential_token_pairrÏ  Ü  s2   € Ü�cœ4× Ò ØÐØ�7‰7�>Ó" C§G¡G¨OÓ$<Ð<Ð<rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   ÚrowsúIterable[Any]rÅ   zdict[str, tuple[Any, Any]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   â  s   € ÷ ]ñ ]˜]ð ]Ð/Iñ ]rË   c                ó|   € \        V 4      P                  4        UUu/ uF  w  rV\        V4      bK  	  upp# u uppi )aJ  Token-generation base per row id, INCLUDING ``(None, None)`` for token-less rows.

A blank base is a known generation ("no pair when we last looked"), so a peer that
later lands a pair on that row is kept by ``_merge_pool_row_generation`` on every
flush alike; dropping blank bases would make the first and later flushes disagree.)Ú
_entry_idsrÀ  rÏ  )rÑ  Úrow_idrË  s   &  rÉ   Ú_token_pairs_by_idrÖ  â  s;   € ô DNÈdÓCS×CYÑCYÔC[Ô\ÑC[±K°FˆFÔ*¨3Ó/Ò/ÑC[Ò\Ð\ùÓ\s   �8Ú	base_pairÚstatus_clearedc               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )rÂ   r¨  rë   Ú
disk_entryr†  rn  rÄ   r×  zOptional[tuple[Any, Any]]rØ  rÆ   rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ë  sL   € ÷ #Gñ #GØð#Gà(ð#Gð ð#Gð
 )ð#Gð ð#Gð ñ#GrË   c               óF  aa	€ ^ RI Hp V'       d   RMSp\        S4      pVe   \        V4      '       d   Ws8X  d   \	        WV4      # \        V 4      o	R VV	3R llpV! \        4       V'       g(   V P                  R4      V8X  d   V! . \        ORN54       \	        S	Wb4      # )af  Keep a newer on-disk token generation authoritative during stale writes.

Only a terminal auth verdict (``last_status == dead``) is scoped to the token pair
it was observed on; account-wide cooldowns (402 billing, 429 throttle) from the
stale writer still apply to the rotated pair and go through the ordinary recency
merge in ``_merge_disk_cooldown_state``.)ÚSTATUS_DEADNc               ó    € V ^8„  d   QhRRRR/# )rÂ   ÚfieldszIterable[str]rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   Ú0_merge_pool_row_generation.<locals>.__annotate__  s   € ÷ (ñ ( ð (°$ñ (rË   c                óh   <€ V  F*  pVS9   d   SV,          SV&   K  SP                  VR 4       K,  	  R # r*  )Úpop)rÞ  r   rÚ  rÃ  s   & €€rÉ   Ú_take_from_diskÚ3_merge_pool_row_generation.<locals>._take_from_disk  s3   ø€ ó ˆEØ˜
Ô"Ø *¨5Õ 1��u“à—
‘
˜5 $Ö'ó	 rË   Úlast_statusÚfailure_reason)	r›  rÜ  rÏ  ÚanyÚ_merge_disk_cooldown_staterö   Ú_POOL_TOKEN_GENERATION_FIELDSrq  Ú_POOL_STATUS_FIELDS)
r¨  rÚ  rn  r×  rØ  rÜ  Ú
merge_diskÚ	disk_pairrâ  rÃ  s
   &f&$$    @rÉ   Ú_merge_pool_row_generationrì  ë  sŽ   ù€ õ 2ç'‘¨Z€JÜ& zÓ2€IØÒ¤ I§¢°)Ô2HÜ)¨%¸[ÓIÐIä�%‹[€F÷(ñ (ñ Ô1Ô2ß˜eŸi™i¨Ó6¸+ÔEÙÐ@Ô-Ð@Ð/?Ñ@ÔAÜ% f¨jÓFÐFrË   c               ó(   € V ^8„  d   QhRRRRRRRR/# )rÂ   r¨  rë   rÚ  r†  rn  rÄ   rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s,   € ÷ /ñ /Øð/Ø'?ð/ØNQð/àñ/rË   c                ó¾  € \        V\        4      '       g   V #  ^ RIHpHpHpHpHp ^ RIH	p V! VP                  R4      V P                  R4      4      p	V	'       d	   / V CRV	/CMT p
\         Uu/ uF  q»VP                  V4      bK  	  ppV! V P                  R4      4      ;'       g    RpV! VP                  R4      4      ;'       g    RpV P                  R4      WE39   d   Wí8”  d   / V
CVC# VP                  R4      pWôV39  d   V
# V P                  R4      ;'       g    R	pVP                  R4      ;'       g    R	pV'       d   V'       d
   VV8w  d   V # V! VP                  R4      4      ;'       g    RpVV8:  d   V
# Wõ8X  d8   V! VP                  W!4      4      pVe   V\        P                  ! 4       8:  d   V
# / V
CVC# u upi   \         d    T u # i ; i)
aK  Keep a newer on-disk cooldown/quarantine over a stale in-memory one.

``write_credential_pool`` persists an in-memory snapshot that may predate another process
marking the same credential exhausted/dead; without this merge the later rewrite resurrects a
rate-limited key as healthy and both processes resume hammering it. The mirror image is a
``hermes auth reset`` that postdates the snapshot's cooldown (``status_cleared_at`` newer than
its ``last_status_at``): the disk row wins there too, or a live session's next ordinary flush
would write the reset cooldown straight back (#89415).)ÚPooledCredentialrÜ  ÚSTATUS_EXHAUSTEDÚ_exhausted_untilÚ_parse_absolute_timestamp)Úmerge_model_cooldownsÚmodel_cooldownsÚlast_status_atg        Ústatus_cleared_aträ  r—  rÍ   )r+  rö   r›  rï  rÜ  rð  rñ  rò  Ú%agent.credential_pool_model_cooldownsró  rq  ré  Ú	from_dictrL  rÖ   )r¨  rÚ  rn  rï  rÜ  rð  rñ  rò  ró  Úmerged_cooldownsrÃ  ÚfÚdisk_status_fieldsÚmem_tsÚ
cleared_tsÚdisk_statusÚ
mem_accessÚdisk_accessÚdisk_tsÚuntils   &&&                 rÉ   rç  rç    sÖ  € ô �j¤$×'Ò'Øˆð"÷	
õ 	
õ 	PÙ0°·±Ð@QÓ1RÐTY×T]ÑT]Ð^oÓTpÓqÐßCSÐ?�EÐ?Ð,Ð.>Ò?ÐY^ˆÝ<OÓPÑ<O°q §¡°Ó!2Ò2Ñ<OÐÐPá*¨5¯9©9Ð5EÓ+FÓG×NÐNÈ3ˆÙ.¨z¯~©~Ð>QÓ/RÓS×ZÐZÐWZˆ
Ø�9‰9�]Ó#¨Ð'FÔFÈ:ÔK^Ø3�fÐ3Ð 2Ð3Ð3Ø —n‘n ]Ó3ˆØÐ,<Ð=Ô=ØˆMð —Y‘Y˜~Ó.×4Ð4°"ˆ
Ø —n‘n ^Ó4×:Ð:¸ˆßŸ+¨*¸Ô*CØˆLÙ+¨J¯N©NÐ;KÓ,LÓM×TÐTÐQTˆØ�fÔØˆMØÔ*Ù$Ð%5×%?Ñ%?ÀÓ%XÓYˆEØŠ} ¬¯ª«Ô 4Ø�Ø/�&Ð/Ð.Ð/Ð/ùò- Qøô. ô ØŠðúsr   šAG ÁG Á/GÂ	G Â) G Ã
%G Ã0G ÄG Ä#G Ä>
G Å	G ÅG ÅG Å8G Æ<G ÇG ÇG ÇGÇGc               ó    € V ^8„  d   QhRRRR/# )rÂ   rž  rÒ  rÅ   zdict[str, dict[str, Any]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   C  s   € ÷ Tñ T˜ð TÐ*Cñ TrË   c                ó²   € V  Uu/ uFF  p\        V\        4      '       g   K  VP                  R 4      '       g   K4  VP                  R 4      VbKH  	  up# u upi )rã   rÎ  )rž  Úes   & rÉ   rÔ  rÔ  C  s=   € Ù$+ÓS¡G˜q¬z¸!¼T×/BŒNÀqÇuÁuÈTÇ{ŒNˆA�E‰E�$‹K˜ŠN¡GÑSÐSùÒSs   …A¢A»AÚremoved_idsÚstatus_cleared_idsÚtoken_basesc               ó0   € V ^8„  d   QhRRRRRRRRRR	R
R/# )rÂ   rn  rÄ   rž  zlist[dict[str, Any]]r  zOptional[Iterable[str]]r  r  z$Optional[dict[str, tuple[Any, Any]]]rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   G  sB   € ÷ )ñ )Øð)Ø3ð)à(ð)ð 0ð)ð 6ð	)ð
 ñ)rË   c               óT  € T;'       g    R Uu0 uF  qU'       g   K  VkK  	  ppT;'       g    / p\        4       ;_uu_ 4        \        4       p\        VR4      p	V U
u. uF&  p
\        V
\        4      '       d   \        W 4      MT
NK(  	  pp
V	P                  V 4      p\        V\        4      '       d   TM. p\        V4      p\        \        V4      4      pT;'       g    R Uu0 uF  qÿ'       g   K  VkK  	  ppV U
u. uFx  p
\        V
\        4      '       d^   \        W­P                  V
P                  R4      4      V VP                  V
P                  R4      4      V
P                  R4      V9   R7      MT
NKz  	  pp
V Fc  p\        V\        4      '       d   VP                  R4      MRpV'       g   K6  VV9  g   K?  VV9  g   KH  VP                  \        VV 4      4       Ke  	  VW�&   \        V4       VuuRRR4       # u upi u up
i u upi u up
i   + '       g   i     R# ; i)a4  Persist one provider's credential pool under auth.json.

Final disk-boundary sanitizer for borrowed credentials (callers may pass raw dicts). Entries on
disk but missing from *entries* (added concurrently) are merged back unless in *removed_ids*,
so a rotation/exhaustion rewrite never drops a concurrent credential. Entries in
*status_cleared_ids* were cleared deliberately (``hermes auth reset``) and skip the
recency merge, which would otherwise read their cleared ``last_status_at`` (None ->
epoch 0) as a stale snapshot and copy a still-binding cooldown back.rd  rã   )r×  rØ  NrÇ   )rZ  rã  r„  r+  rö   r   rq  rÁ  rÔ  Úsetrì  rŸ  r  )rn  rž  r  r  r  ÚridÚremovedÚbasesrz  r§  r  Ú	sanitizedÚexisting_listÚexisting_by_idÚnew_idsÚcidrØ  rÃ  rÚ  Údisk_ids   &&$$$               rÉ   Úwrite_credential_poolr  G  s   € ð  +×0Ð0¨bÐ0Ó9Ñ0�s³S�sˆsÑ0€GÐ9Ø×Ð˜2€EÜ	×	Õ	Ü%Ó'ˆ
Ü˜jÐ*;Ó<ˆñ óá�ô EOÈqÔRV×DWÒDWÔ0°Ô@Ð]^Ò^Ùð 	ð ð Ÿ™ Ó-ˆÜ)3°MÄ4×)HÒ)H™ÈbˆÜ# MÓ2ˆÜ”j Ó+Ó,ˆØ*<×*BÐ*BÀÐ*BÓKÑ*B #ÃsŸ#˜#Ñ*BˆÐKñ ó( ñ �ô ˜!œT×"Ò"ô 'Ø×%Ñ% a§e¡e¨D£kÓ2°KØŸ)™) A§E¡E¨$£KÓ0Ø Ÿu™u T›{¨nÑ<õð
 )*ò*ñ ð 	ð ( ó (ˆJÜ.8¸ÄT×.JÒ.J�j—n‘n TÔ*ÐPTˆGß‰w˜7¨'Ö1°gÀWÖ6LØ—‘ÔBÀ:È{Ó[Ö\ñ (ð #ˆÑÜ˜Ô$Ø÷3 
Ò	ùò :ùò
ùò Lùò( ÷ 
×	Ð	úsZ   �	H�HÁHÁ,HÂ
AHÃ$	HÃ2HÃ8HÃ>A>HÅ<5HÆ6HÆ?HÇ/HÈHÈH'	c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   Ú
suppressedrë   rn  rÄ   rÅ   zOptional[list[str]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   s  s"   € ÷ 	ñ 	¨ð 	ÀSð 	ÐM`ñ 	rË   c                óØ   € V P                  V4      p\        V\        4      '       d   V# \        V\        4      '       d&   V Uu. uF  p\	        V4      NK  	  upW&   W,          # R# u upi )z‰Canonical (list-form) suppressed sources for *provider_id*; a legacy mapping (keys = source
names) is migrated to the list form in place.N)rq  r+  rÁ  rö   rÄ   )r  rn  Úraw_sourcesrä   s   &&  rÉ   Ú_suppressed_source_listr  s  s_   € ð —.‘. Ó-€KÜ�+œt×$Ò$ØÐÜ�+œt×$Ò$Ù9DÓ"E¹°¤3 t¦9¹Ñ"Eˆ
ÑØÕ&Ð&Ùùò #Fs   ÁA'c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rn  rÄ   ry  rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s!   € ÷ 
%ñ 
%¨Cð 
%¸ð 
%Àñ 
%rË   c                óþ   € \        4       ;_uu_ 4        \        4       p\        VR4      p\        W04      pVf   . ;qCV &   W9  d   VP	                  V4       \        V4       RRR4       R#   + '       g   i     R# ; i)z@Mark a credential source as suppressed so it won't be re-seeded.Úsuppressed_sourcesN)rZ  rã  r„  r  rŸ  r  ©rn  ry  rz  r  Úprovider_lists   &&   rÉ   Úsuppress_credential_sourcer     sh   € ä	×	Õ	Ü%Ó'ˆ
Ü# JÐ0DÓEˆ
Ü/°
ÓHˆØÒ Ø68Ð8ˆM {Ñ3ØÔ&Ø× Ñ  Ô(Ü˜Ô$÷ 
×	×	Ò	ús   “AA+Á+A<	c               ó$   € V ^8„  d   QhRRRRRR/# ©rÂ   rn  rÄ   ry  rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Œ  s!   € ÷ ñ  cð °3ð ¸4ñ rË   c                ó‚   €  V\        4       P                  R/ 4      P                  V . 4      9   #   \         d     R# i ; i)z=Check if a credential source has been suppressed by the user.r  F)rã  rq  rÖ   )rn  ry  s   &&rÉ   Úis_source_suppressedr$  Œ  sD   € ðØÔ)Ó+×/Ñ/Ð0DÀbÓI×MÑMÈkÐ[]Ó^Ñ^Ð^øÜô Úðús   ‚,/ ¯>½>c               ó$   € V ^8„  d   QhRRRRRR/# r"  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ”  s!   € ÷ ñ ¨cð ¸3ð À4ñ rË   c                ó¾  € \        4       ;_uu_ 4        \        4       pVP                  R4      p\        V\        4      '       g    RRR4       R# \        W04      pVe   W9  d    RRR4       R# VP                  V4       V'       g   VP                  V R4       V'       g   VP                  RR4       \        V4        RRR4       R#   + '       g   i     R# ; i)zLClear a suppression marker so the source will be re-seeded on the next load.r  NFT)	rZ  rã  rq  r+  rö   r  Úremoverá  r  r  s   &&   rÉ   Úunsuppress_credential_sourcer(  ”  s©   € ä	×	Õ	Ü%Ó'ˆ
Ø—^‘^Ð$8Ó9ˆ
Ü˜*¤d×+Ò+Ø÷	 
Ñ	ô
 0°
ÓHˆØÒ  FÔ$?Ø÷ 
Ñ	ð 	×Ñ˜VÔ$ßØ�N‰N˜;¨Ô-ßØ�N‰NÐ/°Ô6Ü˜Ô$Ø÷ 
×	×	Ò	ús#   “3CÁCÁ0CÂ	CÂ#CÃC	c               ó    € V ^8„  d   QhRRRR/# )rÂ   rn  rÄ   rÅ   r†  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   §  s   € ÷ Añ A¨ð AÐ1Iñ ArË   c                ó*   € \        \        4       V 4      # )zSPersisted auth state for a provider (profile first, global-root fallback), or None.)r‘  rã  )rn  s   &rÉ   Úget_provider_auth_stater+  §  s   € äÔ 0Ó 2°KÓ@Ð@rË   c               ó   € V ^8„  d   QhRR/# )rÂ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ¬  s   € ÷ 6ñ 6 dñ 6rË   c                 óÒ   €  \        R4      ;'       g    / p T P                  R4      p\        T\        4      '       g   R# \
        TP                  4       9   #   \         d     R# i ; i)a�  Return True if the currently-held Nous token carries ``billing:manage``.

Reads the persisted ``scope`` string saved at login (``_save_provider_state``
stores ``token_data.get("scope") or scope``). A space-delimited match. Used by
the lazy step-up: if False, the first billing call will 403 ``insufficient_scope``
anyway, but checking up front lets a surface skip a doomed round-trip.
rü   Fré   )r+  rÖ   rq  r+  rÄ   r�   r%  )rˆ  ré   s     rÉ   Únous_token_has_billing_scoper.  ¬  s^   € ðÜ'¨Ó/×5Ð5°2ˆð �I‰I�gÓ€EÜ�eœS×!Ò!ÙÜ$¨¯©«Ñ5Ð5øô ô Úðús   ‚A ”A ÁA&Á%A&c               ó   € V ^8„  d   QhRR/# ©rÂ   rÅ   rz  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ¾  s   € ÷ 5ñ 5˜]ñ 5rË   c                 ó4   € \        4       P                  R4      # )z8Return the currently active provider ID from auth store.rg  )rã  rq  rÇ   rË   rÉ   Úget_active_providerr2  ¾  s   € äÓ×!Ñ!Ð"3Ó4Ð4rË   c               ó    € V ^8„  d   QhRRRR/# ©rÂ   r¯  rÄ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ã  s   € ÷ 1ñ 1 Cð 1¨Dñ 1rË   c                ó®   € \        4       P                  R 4      ;'       g    RP                  4       P                  4       p\	        V4      ;'       d    W8H  # )rg  rÍ   )rã  rq  rÜ   rÔ   rÆ   )r¯  Úactives   & rÉ   Ú_active_provider_isr7  Ã  sE   € ÜÓ ×$Ñ$Ð%6Ó7×=Ð=¸2×DÑDÓF×LÑLÓN€FÜ�‹<×0Ð0˜FÑ0Ð0rË   c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   Úslotr   r¯  rÄ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   È  s&   € ÷ añ a˜ð a¨ð a°ñ arË   c                ó¦   € \        V \        4      ;'       d;    V P                  R 4      ;'       g    RP                  4       P	                  4       V8H  # )r‡  rÍ   )r+  rö   rq  rÜ   rÔ   )r9  r¯  s   &&rÉ   Ú_slot_selectsr;  È  s@   € Ü�dœDÓ!×`Ð` t§x¡x°
Ó';×'AÐ'A¸r×&HÑ&HÓ&J×&PÑ&PÓ&RÐV`Ñ&`Ð`rË   c               ó    € V ^8„  d   QhRRRR/# r4  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ì  s   € ÷ Vñ V¨ð V°ñ VrË   c                óÚ  a a€ ^ RI Hp V! 4       p\        VP                  R4      S 4      '       d   R# VP                  R4      p\	        V\
        4      '       d_   \        ;QJ d-    V 3R lVP                  4        4       F  '       g   K   RM"	  RM! V 3R lVP                  4        4       4      '       d   R# R V 3R lloVP                  R	4      p\	        V\
        4      '       g   R# VP                  R
4      p\	        V\
        4      '       d   VP                  4       MRpS! V4      ;'       g;    \        ;QJ d    V3R lV 4       F  '       g   K   R# 	  R# ! V3R lV 4       4      # )a´  config.yaml ``model.provider``, or a MoA advisor/aggregator slot naming the provider.

MoA presets are explicit model selections too: ``provider: anthropic`` in a MoA slot opts into
Anthropic credentials for that slot even when the main model is another provider; otherwise
Claude Code OAuth entries get pruned by ``load_pool("anthropic")`` and MoA advisors fail with
"no ANTHROPIC_API_KEY" while the picker says Anthropic is logged in.r„  r†  TÚ	auxiliaryc              3  ó<   <"  € T F  p\        VS4      x € K  	  R # 5ir*  ©r;  ©r,  Úsr¯  s   & €rÉ   r.  Ú+_config_selects_provider.<locals>.<genexpr>Ú  s   øé € Ð(`ÑO_È!¬°q¸*×)EÐ)EÓO_ùó   ƒFc               ó    € V ^8„  d   QhRRRR/# )rÂ   Úblockr   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   Ú._config_selects_provider.<locals>.__annotate__Ý  s   € ÷ Cñ C #ð C¨$ñ CrË   c                óR  <€ \        V \        4      ;'       d�    \        ;QJ d8    V3R  lV P                  R4      ;'       g    .  4       F  '       g   K   RM-	  RM)! V3R  lV P                  R4      ;'       g    .  4       4      ;'       g    \	        V P                  R4      S4      # )c              3  ó<   <"  € T F  p\        VS4      x € K  	  R # 5ir*  r@  rA  s   & €rÉ   r.  ÚG_config_selects_provider.<locals>._moa_block_matches.<locals>.<genexpr>ß  s   øé € ÐZÑ6Y°”˜a ×,Ð,Ó6YùrD  Úreference_modelsTFÚ
aggregator)r+  rö   ræ  rq  r;  )rF  r¯  s   &€rÉ   Ú_moa_block_matchesÚ4_config_selects_provider.<locals>._moa_block_matchesÝ  sˆ   ø€ Ü˜%¤Ó&÷ Cð Cß‹CÔZ°e·i±iÐ@RÓ6S×6YÐ6YÐWYÐ6YÓZ�C�CŠCÔZ°e·i±iÐ@RÓ6S×6YÐ6YÐWYÐ6YÓZÓZ÷ Bð BÜ˜UŸY™Y |Ó4°jÓAð	CrË   r¸  Úpresetsc              3  ó4   <"  € T F  pS! V4      x € K  	  R # 5ir*  rÇ   )r,  ÚprM  s   & €rÉ   r.  rC  ç  s   øé € Ð-UÉWÈÑ.@À×.CÐ.CËWùs   ƒrÇ   )rE  r…  r;  rq  r+  rö   ræ  Úvalues)r¯  r…  ÚcfgÚaux_cfgÚmoa_cfgrO  rM  s   f     @rÉ   Ú_config_selects_providerrV  Ì  sÿ   ù€ õ .Ù
‹-€CÜ�S—W‘W˜WÓ% z×2Ò2Ùð �g‰g�kÓ"€GÜ�'œ4× Ò §S£SÔ(`ÈwÏ~É~ÔO_Ó(`§S§S¢SÔ(`ÈwÏ~É~ÔO_Ó(`×%`Ò%`Ù÷Cð Cð
 �g‰g�e‹n€GÜ�gœt×$Ò$ÙØ�k‰k˜)Ó$€GÜ",¨W´d×";Ò";ˆg�n‰nÔÀ€GÙ˜gÓ&×UÐU¯#«#Ô-UÉWÓ-U¯#¬#ÐUª#ÐU¨#Ô-UÉWÓ-UÓ*UÐUrË   c               ó    € V ^8„  d   QhRRRR/# r4  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ê  s   € ÷ ]ñ ]¨Sð ]°Tñ ]rË   c                óŽ   € \         ;QJ d%    R \        V 4       4       F  '       g   K   R# 	  R# ! R \        V 4       4       4      # )z®Pool rows from EXPLICIT Hermes flows (manual add / device-code / PKCE) or live env keys;
ambient borrowed sources (gh_cli / claude_code / qwen-cli) are deliberately excluded.c              3  ó8   "  € T F  p\        V4      x € K  	  R # 5ir*  )Ú_pool_entry_is_explicit)r,  r¨  s   & rÉ   r.  Ú/_explicit_pool_entry_present.<locals>.<genexpr>í  s   é € Ð\Ñ;[°%Ô& u×-Ð-Ó;[ùs   ‚TF)ræ  rÉ  )r¯  s   &rÉ   Ú_explicit_pool_entry_presentr\  ê  s;   € ÷ ‹3Ñ\Ô;OÐPZÔ;[Ó\�3Œ3Ð\Š3Ð\ˆ3Ñ\Ô;OÐPZÔ;[Ó\Ó\Ð\rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   rä   rÄ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ö  s   € ÷ Fñ F�cð F˜dñ FrË   c                óD   € ^ RI Hp \        V! V 4      ;'       g    R4      # )uº  True when *name* resolves to a usable secret in the active profile scope.

Must not read raw ``os.getenv``: under ``hermes serve`` / Desktop multiplex the
process environ is the *launch* profile, so a DeepSeek key pasted into another
profile's ``.env`` would be invisible to ``explicit_only`` Settings â†’ Model
until a Bot-chat Refresh ran against that profile's own backend.
Same reader as the credential resolver (``get_env_value_prefer_dotenv``: the current
HERMES_HOME ``.env`` first, then the scope-checked environ) so the gate and the key that
actually authenticates never disagree â€” an empty ``DEEPSEEK_API_KEY=`` export in the parent
shell must not hide a real key in ``.env`` (#77007).
r;  rÍ   )rE  r<  rj  )rä   r<  s   & rÉ   Ú_env_secretr_  ö  s    € õ >ÜÑ8¸Ó>×DÐDÀ"ÓEÐErË   c               ó    € V ^8„  d   QhRRRR/# r4  rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s   € ÷ ñ °#ð ¸$ñ rË   c                óž  € \         P                  V 4      pVf   ^ RIHp V! V 4      pV'       g   R# VP                  R8X  dI   \
        ;QJ d&    R VP                   4       F  '       g   K   R# 	  R# ! R VP                   4       4      # VP                  R8X  d2   \        R4      ;'       g    \        R4      ;'       d    \        R	4      # R# )
u?  True when the user has pasted an explicit credential env var for *normalized*.

Falls back to the models.dev ``ProviderDef`` (same shape) for non-registry providers such as
openrouter. AWS SDK providers are checked via explicit env vars only â€” NOT boto3's chain, so
ambient EC2 IMDS / SSO profiles never auto-surface.)Úget_providerFrø   c              3  óP   "  € T F  q\         9  g   K  \        V4      x € K  	  R # 5ir*  )Ú_IMPLICIT_ENV_VARSr_  r>  s   & rÉ   r.  Ú4_explicit_env_credentials_present.<locals>.<genexpr>  s    é € ÐcÑ+C aÔPbÑGb”>”;˜q—>�>Ó+Cùs   ‚&“&Tr&  ÚAWS_BEARER_TOKEN_BEDROCKÚAWS_ACCESS_KEY_IDÚAWS_SECRET_ACCESS_KEY)r/  rq  Úhermes_cli.providersrb  rå   ræ  rî   r_  )r¯  r�  rb  s   &  rÉ   Ú!_explicit_env_credentials_presentrj    s²   € ô  ×#Ñ# JÓ/€GØ‚Ý5Ù˜zÓ*ˆßÙØ×Ñ˜IÔ%ß‹sÑc¨7×+CÒ+CÓc�sŒsÐcŠsÐcˆsÑc¨7×+CÒ+CÓcÓcÐcØ×Ñ˜IÔ%ÜÐ5Ó6÷ Wð WÜÐ+Ó,×UÐU´Ð=TÓ1Uð	WárË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   r¨  r   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s   € ÷ _ñ _ 3ð _¨4ñ _rË   c                óô  € \        V \        4      '       g   R# \        V P                  R4      ;'       g    R4      P	                  4       P                  4       pVP                  R4      '       dV   V P                  RR4      P                  R^4      ^,          P	                  4       p\        T;'       d    \        V4      4      # \        V4      ;'       d#    V\        9   ;'       g    VP                  R4      # )zZTrue for pool rows the user created via an explicit Hermes flow (or a still-live env key).Fry  rÍ   zenv:Ú:zmanual:)r+  rö   rÄ   rq  rÜ   rÔ   rY  r%  rÆ   r_  Ú_EXPLICIT_POOL_SOURCES)r¨  ry  r¥  s   &  rÉ   rZ  rZ    sÁ   € ä�eœT×"Ò"ÙÜ�—‘˜8Ó$×*Ð*¨Ó+×1Ñ1Ó3×9Ñ9Ó;€FØ×Ñ˜× Ò ð —)‘)˜H bÓ)×/Ñ/°°QÓ7¸Õ:×@Ñ@ÓBˆÜ�G×4Ð4¤¨GÓ 4Ó5Ð5Ü�‹<×^Ð^˜VÔ'=Ñ=×]Ð]À×ARÑARÐS\ÓA]Ð^rË   c               ó    € V ^8„  d   QhRRRR/# r4  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   (  s   € ÷ ñ °cð ¸dñ rË   c                ó4  € V \         9   d   ^ RIHp \        V! 4       4      # V R8X  dp   ^ RIHp V! 4       P                  R4      p\        V\        4      ;'       d<    \        \        VP                  R4      ;'       g    R4      P                  4       4      # R# )ah  Vertex / Bedrock count as explicit when Hermes-scoped routing config is present.

Uses has_explicit_vertex_config(), NOT has_vertex_credentials(): the latter also counts an
ambient GOOGLE_APPLICATION_CREDENTIALS path (commonly set for unrelated GCP work). Only
Hermes-scoped signals (VERTEX_PROJECT_ID / vertex.project_id / VERTEX_CREDENTIALS_PATH) count
here.)Úhas_explicit_vertex_configr%  r„  r  rÍ   F)Ú_VERTEX_PROVIDER_IDSÚagent.vertex_adapterrq  rÆ   rE  r…  rq  r+  rö   rÄ   rÜ   )r¯  rq  r…  Úbedrock_cfgs   &   rÉ   Ú%_keyless_provider_has_explicit_configru  (  sy   € ð Ô)Ô)ÝCÜÑ.Ó0Ó1Ð1Ø�YÔÝ1Ù!“m×'Ñ'¨	Ó2ˆÜ˜+¤tÓ,×cÐc´´c¸+¿/¹/È(Ó:S×:YÐ:YÐWYÓ6Z×6`Ñ6`Ó6bÓ1cÐcÙrË   z.tuple[tuple[Callable[[str], bool], bool], ...]Ú_EXPLICIT_CONFIG_CHECKSc               ó    € V ^8„  d   QhRRRR/# r«  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   B  s   € ÷ ñ °3ð ¸4ñ rË   c                ó  € T ;'       g    RP                  4       P                  4       p\         F  w  r# V! V4      '       d    R# K  	  R#   \         d6   pT'       g   h \        P                  RTP                  Y4        Rp?KX  Rp?ii ; i)af  True only if the user explicitly configured this provider: auth.json ``active_provider``,
config.yaml ``model.provider`` / MoA slots, a pasted provider env var, a pool entry from a
Hermes-initiated flow, or Hermes-scoped routing config for keyless cloud-SDK providers. Ambient
borrowed credentials (gh CLI, qwen-cli, ~/.claude/.credentials.json) never count.rÍ   Tz*explicit-config check %s failed for %s: %sNF)rÜ   rÔ   rv  rÖ   r|  rl  rð   )rn  r¯  ÚcheckÚbest_effortr¤  s   &    rÉ   Ú!is_provider_explicitly_configuredr{  B  s�   € ð
 ×#Ð# ×*Ñ*Ó,×2Ñ2Ó4€Jß5Ñˆð	iÙ�Z× Ò Úñ !ñ 6ñ øô	 ô 	ißØÜ�L‰LÐEÀuÇ~Á~ÐWb×hÒhûð	iús   µAÁBÁ*BÂBc               ó    € V ^8„  d   QhRRRR/# ©rÂ   rn  rz  rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   S  s   € ÷ ñ  ]ð ¸dñ rË   c                ó|  € \        4       ;_uu_ 4        \        4       pT ;'       g    VP                  R4      pV'       g    RRR4       R# RpR F  p\        W4      pW%9   g   K  WR RpK  	  VP                  R4      V8X  d   RVR&   RpV'       d   \	        V4       VuuRRR4       #   + '       g   i     R# ; i)zŽClear auth state for a provider (the active one when *provider_id* is None). Used by
``hermes logout``. Returns True if something was cleared.rg  NFT)r^  rd  )rZ  rã  rq  r„  r  )rn  rz  rr  Úclearedrƒ  rž  s   &     rÉ   Úclear_provider_authr€  S  s¦   € ô 
×	Õ	Ü%Ó'ˆ
Ø×AÐA 
§¡Ð/@Ó AˆßØ÷	 
Ñ	ð
 ˆÛ7ˆGÜ$ ZÓ9ˆGØÖ Ø�OØ’ñ	 8ð
 �>‰>Ð+Ó,°Ô6Ø,0ˆJÐ(Ñ)ØˆGßÜ˜ZÔ(Ø÷! 
×	×	Ó	ús#   “-B*ÁB*ÁB*Á&,B*ÂB*Â*B;	c               ó   € V ^8„  d   QhRR/# ©rÂ   rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   i  s   € ÷ %ñ %˜Tñ %rË   c                 ó˜   € \        4       ;_uu_ 4        \        4       p RV R&   \        V 4       RRR4       R#   + '       g   i     R# ; i)z¸Clear active_provider without deleting credentials: used when the user switches to a non-OAuth
provider (OpenRouter, custom) so auto-resolution doesn't keep picking the OAuth provider.Nrg  )rZ  rã  r  )rz  s    rÉ   Údeactivate_providerr„  i  s7   € ô 
×	Õ	Ü%Ó'ˆ
Ø(,ˆ
Ð$Ñ%Ü˜Ô$÷ 
×	×	Ò	ús	   “8¸A		c               ó    € V ^8„  d   QhRRRR/# )rÂ   Úprovider_namerÄ   rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   u  s   € ÷ ñ ¸ð Àñ rË   c                óH  € \        T ;'       g    R4      P                  4       P                  4       R9   d   R#  ^ RIHp V! 4       pV'       g   R# R.pV F§  pTP                  RVP                  R8X  d   RMR R	VP                   24       VP                  '       g   KK  VP                  P                  4       ^ ,          '       g   Kt  VP                  R
VP                  P                  4       ^ ,           24       K©  	  RP                  V4      #   \         d     R# i ; i)z<Return a helpful hint string when provider resolution fails.rÍ   a'  OpenCode discontinued anonymous free-tier access outside its own client (relay 403s FreeTierError), so the keyless 'opencode-free' provider was removed. Switch to 'opencode-zen' (pay-as-you-go, OPENCODE_ZEN_API_KEY) or 'opencode-go' ($10/mo subscription, OPENCODE_GO_API_KEY) via 'hermes model'.)Úvalidate_config_structureuC   Config issue detected â€” run 'hermes doctor' for full diagnostics:z  [r­  ÚERRORÚWARNINGz] u       â†’ r0  >   ÚfreeÚopencode_freeúopencode-free)rÄ   rÜ   rÔ   rE  rˆ  rŸ  ÚseverityÚmessagerS  Ú
splitlinesr~  rÖ   )r†  rˆ  ÚissuesÚlinesÚcis   &    rÉ   Ú%_get_config_hint_for_unknown_providerr”  u  sñ   € ä
ˆ=×Ð˜BÓ×%Ñ%Ó'×-Ñ-Ó/Ð3]Ô]ñQðÝ?Ù*Ó,ˆßÙØVÐWˆÛˆBØ�L‰L˜3¨"¯+©+¸Ô*@™wÀiÐPÐPRÐSU×S]ÑS]ÐR^Ð_Ô`Ø�w�wŠw˜2Ÿ7™7×-Ñ-Ó/°×2Ö2Ø—‘˜x¨¯©×(:Ñ(:Ó(<¸QÕ(?Ð'@ÐAÖBñ ð �y‰y˜ÓÐøÜô Úðús%   ºD ÁAD Â!$D Ã
AD ÄD!Ä D!c               ó   € V ^8„  d   QhRR/# r‚  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ‹  s   € ÷ ñ °ñ rË   c                 óÌ   €  ^ RI Hp  V ! 4       pV'       g   R# \        4       p\        RT RT R2RR7      h  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)	aO  Refuse env-key/pool auto-adoption of openrouter while config.yaml is corrupt.

A corrupt config loads as ``DEFAULT_CONFIG`` (no ``model.provider``), so the env sniff would
silently adopt the PAID openrouter provider over whatever the broken config really names.
Fires ONLY on the auto path and clears itself once the file parses again.)Úget_active_config_parse_failureNz.Could not probe config parse-failure state: %szconfig.yaml at z is corrupt (uŒ   ) â€” refusing to auto-select an inference provider from environment keys. Fix the YAML (a backup was saved next to it) or run hermes setup.Úcorrupt_config©r°  )Úhermes_cli.config_read_errorsr—  r2  rÖ   r|  rl  r¾   )r—  ÚerrrÝ   r  s       rÉ   Ú&_refuse_env_adoption_if_config_corruptrœ  ‹  so   € ðÝQÙ-Ó/ˆßÙÜÓ ˆô Ø
˜$˜˜}¨S¨Eð 25ð 	6ð ô	ð øô ô Ü�‰ÐEÀqÔIÝûðús   ‚7 ™
7 ·A#ÁAÁA#Úglmzz-aizz.aiÚzhipuÚgooglezgoogle-geminizgoogle-ai-studiozx-aizx.aiÚgrokz
x-ai-oauthz
grok-oauthzxai-grok-oauthÚkimizkimi-for-codingÚmoonshotzkimi-cnzmoonshot-cnÚstepzstepfun-coding-planzarcee-aiÚarceeaiz	gmi-cloudÚgmicloudzactual-computerÚactualcomputerÚacizminimax-chinaÚ
minimax_cnzminimax-portalzminimax-globalÚminimax_oauthÚalibaba_codingzalibaba-codingÚalibaba_coding_planÚclaudezclaude-codeÚgithubzgithub-copilotzgithub-modelszgithub-modelzgithub-copilot-acpzcopilot-acp-agentÚ	aigatewayÚvercelzvercel-ai-gatewayÚopencodeÚzenzqwen-portalzqwen-cliÚhfzhugging-facezhuggingface-hubÚmimozxiaomi-mimoÚtencentÚtokenhubztencent-cloudÚtencentmaasÚ	tokenplanztencent-lkeapÚawszaws-bedrockzamazon-bedrockÚamazonÚgozopencode-go-subÚkiloz	kilo-codezkilo-gatewayz	lm-studioÚ	lm_studioÚchatgptzchatgpt-codexr   rº  ÚollamaÚollama_cloudÚvllmÚllamacppz	llama.cppz	llama-cppúdict[str, str]Ú_PROVIDER_ALIASESc               ó   € V ^8„  d   QhRR/# )rÂ   rÅ   rÂ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ì  s   € ÷ 
ñ 
˜ñ 
rË   c                 óÎ   € \        \        4      p  ^ RIHp V! 4        F1  pVP                   F  pV P                  W2P                  4       K   	  K3  	  V #   \         d     T # i ; i)zX``_PROVIDER_ALIASES`` extended with aliases declared in plugins/model-providers/<name>/.)Úlist_providers)rö   rÃ  r^  rÆ  Úaliasesrþ  rä   rÖ   )rÇ  Ú_lpÚ_ppÚ_aliass       rÉ   Ú_plugin_aliasesrË  Ì  sa   € äÔ$Ó%€GðÝ3Ù–5ˆCØŸ+œ+�Ø×"Ñ" 6¯8©8Ö4ó &ñ ð
 €Nøô ô ØØ€Nðús   ‘AA ÁA$Á#A$c               ó   € V ^8„  d   QhRR/# )rÂ   rÅ   úCallable[[str], str]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ù  s   € ÷ 2ñ 2Ð 4ñ 2rË   c                 óh   €  ^ RI Hp  V #   \         d    \        P	                  RR4       R u # i ; i)a   Scope-aware key reader for provider auto-detection.

Under multiplex a secondary profile's keys live only in its secret scope, not os.environ. Catch
ONLY ImportError: any other auxiliary_client failure must propagate rather than silently
falling back to os.getenv (a traceless fail-open).©Ú_scoped_key_envu·   agent.auxiliary_client unavailable (%s); provider auto-detection will read keys from the process environment only â€” under multiplex, secondary profiles may report 'No LLM provider'.zimport failedc                óB   € \         P                  ! V 4      ;'       g    R # r³  )rÊ  Úgetenv)rä   s   &rÉ   Ú<lambda>Ú(_scoped_key_env_reader.<locals>.<lambda>ë  s   € œBŸIšI d›O×1Ð1¨rÐ1rË   )Úagent.auxiliary_clientrÐ  ÚImportErrorr|  r}  rÏ  s    rÉ   Ú_scoped_key_env_readerr×  Ù  s@   € ð2õ 	;ØÐøÜô 2Ü�‰ðJð ô		ñ
 2Ò1ð2ús   ‚
 Š$1°1c               ó    € V ^8„  d   QhRRRR/# )rÂ   Úscoped_key_envrÍ  rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   î  s   € ÷ ñ Ð.Bð Àtñ rË   c                ó6  € \        V ! R4      4      '       d   R# V ! R4      p\        V4      '       d   \        V4      '       d   R#  ^ RIHp \	        V! R4      P                  4       4      #   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)	zöTrue when an OpenRouter credential exists via env key or the credential pool (a key added via
`hermes auth add openrouter` has no env var; without the pool check it is invisible to
auto-detection and requests go out with no Authorization header).ÚOPENROUTER_API_KEYTÚOPENAI_API_KEYr“  rk  z.Could not check OpenRouter credential pool: %sNF)	rj  rw  r›  r”  rÆ   rœ  rÖ   r|  rl  )rÙ  Ú
legacy_keyÚ
_load_poolr  s   &   rÉ   Ú_openrouter_auto_detectedrß  î  s„   € ô ™Ð(<Ó=×>Ò>Ùñ  Ð 0Ó1€JÜ˜×$Ò$Ô)BÀ:×)NÒ)NÙð
õ 	BÜ‘J˜|Ó,×<Ñ<Ó>Ó?Ð?øÜô Ü�‰ÐEÀqÔIÝûðús   Á$A, Á,BÁ7BÂBÚskip_free_tierc               ó    € V ^8„  d   QhRRRR/# )rÂ   rà  rÆ   rÅ   rz  rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s   € ÷ ñ ¸ð Èñ rË   c                óh  €  \        4       P                  R4      pVR8X  d-   ^ RIHpHp V! 4       '       d   V '       g   V! 4       '       g   R# V'       d.   V\
        9   d#   \        V4      P                  R4      '       d   V# R#   \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i)zTauth.json ``active_provider`` when it is a registry provider that reports logged in.rg  rü   )Úfree_inference_activeÚ	has_guestNÚ	logged_inz+Could not pre-read active auth provider: %s)
rã  rq  Úhermes_cli.anon_authrã  rä  r/  Úget_auth_statusrÖ   r|  rl  )rà  Ú_mayberã  rä  r  s   $    rÉ   Ú _logged_in_oauth_active_providerré    s�   € ð	GÜ!Ó#×'Ñ'Ð(9Ó:ˆØ�VÔßMÙ�{Š{§Ñ6K×6MÒ6MÙß�fÔ 1Ô1´oÀfÓ6M×6QÑ6QÐR]×6^Ò6^ØˆMñ øô ô GÜ�‰ÐBÀA×FÐFÙûðGús-   ‚4B ·B ¿B ÁB Á,B ÂB1ÂB,Â,B1c               ó   € V ^8„  d   QhRR/# )rÂ   rÅ   ztuple[Any, Optional[str]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s   € ÷ 'ñ 'Ð 9ñ 'rË   c                 ó*  €  ^ RI Hp  V ! 4       ;'       g    / P                  R4      p\        V\        4      '       d   VP                  R4      MRp\        V\
        4      '       d   VP                  4       P                  4       MRp\        4       P                  W"4      pVR8X  g   VP                  R4      '       d   VR3# VR8X  g   V\        9   d   W3# V'       d   ^ R	IHp V! V4      '       d   VR3# \        V\        4      '       d3   \        VP                  R
4      ;'       g    R4      P                  4       MRpV'       d   ^ RIHp V! WB4      '       d   VR3# VR3#   \         d#   p\         P#                  RT4       Ru Rp?# Rp?ii ; i)aõ  ``(model_cfg, provider)`` from config.yaml when ``model.provider`` names a registry provider
or a custom OpenAI-compatible endpoint (``custom``, ``custom:<name>``, ``vllm``/``ollama``/...).
A ``model.provider: openrouter`` pin and a bare ``providers:`` entry name are explicit intent too.

The normal chat/gateway path resolves config.provider upstream in resolve_requested_provider();
this is the safety net for the direct ``resolve_provider("auto")`` callers. A configured custom
endpoint is explicit intent like any registry pin: without this rung the boot inventory
(``free_tier_bootstrap``) read a llama.cpp/vLLM install as "nothing configured" and the
dashboard's Ink chat parked every session on Setup Required while ``hermes chat`` worked
(#108383).r„  r†  r‡  NrÍ   rº  r·  rk  )Úhas_named_custom_providerrÃ   )Ú,_config_base_url_trustworthy_for_bare_customzACould not read config.yaml model.provider for auto-resolution: %srŒ  )rE  r…  rq  r+  rö   rÄ   rÜ   rÔ   rË  rY  r/  Ú"hermes_cli.runtime_provider_customrì  Úhermes_cli.runtime_providerrí  rÖ   r|  rl  )r…  rŠ  r‡  rì  rÃ   rí  r  s          rÉ   Ú_config_model_providerrð    sW  € ðÝ1Ù “]×(Ð( b×-Ñ-¨gÓ6ˆ	Ü0:¸9Äd×0KÒ0K�9—=‘= Ô,ÐQUˆÜ/9¸(ÄC×/HÒ/H�8—>‘>Ó#×)Ñ)Ô+ÈbˆÜ"Ó$×(Ñ(¨Ó<ˆØ�xÔ 8×#6Ñ#6°y×#AÒ#AØ˜hÐ&Ð&ð �|Ô# xÔ3DÔ'DØÐ&Ð&÷ ÝTÙ(¨×2Ò2Ø  (Ð*Ð*ô DNÈiÔY]×C^ÒC^”3�y—}‘} ZÓ0×6Ð6°BÓ7×=Ñ=Ô?ÐdfˆßÝ`Ù;¸H×OÒOØ  (Ð*Ð*Ø˜$ˆÐøÜô Ü�‰ÐXÐZ[Ô\ØÕûðúsY   ‚E% –B'E% Â>E% ÃE% ÃE% ÃE% Ã3E% Ã72E% Ä*E% Å	E% Å!E% Å%FÅ0FÆFÆFc               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rÙ  rÍ  Úoauth_activerz  rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   F  s$   € ÷ ñ Ø(ðØ8EðØJWñrË   c           	     ó&  € \         P                  4        Fx  w  r#VP                  R8w  g   V\        9   d   K#  VP                   FE  p\        V ! V4      4      '       g   K  V'       d   W8w  d   \        P                  RW$W4       Vu u # 	  Kz  	  R# )zµFirst registry api_key provider (registry order) with a usable env key, warning when it
preempts a logged-in OAuth provider so a stale key in ~/.hermes/.env never switches silently.rø   zžProvider resolved to %r via %s, preempting your logged-in OAuth provider %r. If you meant to use the OAuth login, unset %s or set `model.provider` explicitly.N)r/  rÀ  rå   Ú_NO_AUTO_DETECT_PROVIDERSrî   rj  r|  r}  )rÙ  rò  r+  r�  r¥  s   &&   rÉ   Ú_env_key_auto_detectedrõ  F  s~   € ô *×/Ñ/Ö1‰ˆØ×Ñ 	Ô)¨SÔ4MÔ-MÙØ×/Ô/ˆGÜ ¡°Ó!8×9Ô9ß LÔ$7Ü—N‘Nð&ð  lô=ð ”
ó 0ñ 2ñ  rË   Úexplicit_api_keyÚexplicit_base_urlc          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# )	rÂ   Ú	requestedrz  rö  r÷  rà  rÆ   rÅ   rÄ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ]  sC   € ÷ ['ñ ['Øð['ð $ð['ð %ð	['ð
 ð['ð
 &)ñ['rË   c               óò  € T ;'       g    RP                  4       P                  4       p\        4       P                  WD4      pVR9   g   \	        V4      e   V# VR8w  d3   \        V4      pV'       d   RV 2MRp\        RV R2V,           RR	7      hV'       g	   V'       d   R# \        4       w  rxV'       d   V# \        4       p	\        V	4      '       d   \        4        R# \        VR
7      p
\        Wš4      pV'       d   V# V
'       dN   \        V\        4      '       d6   V'       d.   VP                  R4      '       g   \        P!                  RV
4       V
# V'       g    ^ RIHp V! 4       '       d   R#   ^ RIHp ^ RIHp V! V! 4       '       * R7      '       d   R#  ^ RIHp \        RV! 4        R2RR	7      h  \&         d!   p\        P)                  RT4        Rp?LkRp?ii ; i  \0         d     LWi ; i)aJ  Determine which inference provider to use.

"auto" priority (explicit intent beats a stale OAuth login): 1. CLI api_key/base_url ->
"openrouter"; 2. config.yaml ``model.provider``; 3. OPENROUTER_API_KEY (or an sk-or- key in
OPENAI_API_KEY) -> "openrouter"; 4. OpenRouter pool; 5. provider env keys; 6. auth.json ``active_provider``;
7. Nous free tier when a claimed guest exists on the desktop's local backend (never created here);
8. AWS Bedrock chain; 9. AuthError(no_provider_configured).

``skip_free_tier`` hides rungs 6-for-a-free-tier-identity and 7: the boot bootstrap asks
"what would carry inference if the free tier did not exist?" to decide whether a fresh identity
may become ``active_provider``.

1. 3. 4. 5. Provider-specific API keys (GLM, Kimi, MiniMax, ...) -> that provider 7. 8. Error (no
provider configured) See #29285.
r¹  rk  Nz

z` Check 'hermes model' for available providers, or run 'hermes doctor' to diagnose config issues.zUnknown provider 'z'.Úinvalid_providerr™  )rà  r‡  z§Provider resolved to logged-in OAuth provider %r because config.yaml `model` has no `provider` key. If you meant a different provider, set `model.provider` explicitly.)rã  rü   z6free tier check during provider resolution skipped: %s©Úhas_aws_credentials)Úon_local_desktop_backend)Úinstance_metadatar%  )Údisplay_hermes_homezÏHermes is not connected to any AI provider yet. Run `hermes model` to pick one, type `/login` in chat, or add a key with `hermes auth add <provider>`. (Advanced: put an API key such as OPENROUTER_API_KEY in z/.env.)Úno_provider_configured)rk  rº  )rÜ   rÔ   rË  rq  r­  r”  r¾   rð  r×  rß  rœ  ré  rõ  r+  rö   r|  r}  ræ  rã  rÖ   rl  Úagent.bedrock_adapterrý  rþ  rÖ  r¼  r   )rù  rö  r÷  rà  r¯  rS  ra  Ú
_model_cfgÚcfg_providerrÐ  Ú_oauth_activeÚenv_pidrã  r¤  rý  rþ  r   s   &$$$             rÉ   r»  r»  ]  sÖ  € ð* ×%Ð%˜v×,Ñ,Ó.×4Ñ4Ó6€JÜ Ó"×&Ñ& zÓ>€JàÐ-Ô-Ô1AÀ*Ó1MÒ1YØÐØ�VÔÜ4°ZÓ@ˆß!%�$�t�f‘ð ,DˆäÐ,¨Z¨L¸Ð;¸dÕBÐI[Ô\Ð\ç×,Ùä5Ó7Ñ€JßØÐä,Ó.€OÜ  ×1Ò1Ü.Ô0Ùô 5ÀNÔS€MÜ$ _ÓD€GßØˆ÷ Ü�j¤$×'Ò'¯J¸z¿~¹~Èj×?YÒ?YÜ�N‰NðGð ô	ð
 Ð÷ ð	XÝBÙ$×&Ò&Ùð 'ðÝ=ÝAÙÑ5MÓ5OÔ1O×PÓPÙð Qõ 5Ü
ð	sáÓ Ð
! ð	*ð &ô	'ð 'øô ô 	XÜ�L‰LÐQÐSV×WÑWûð	Xûô ô Ùðús*   ÅF: Å6$G( Æ:G%ÇG Ç G%Ç(G6Ç5G6c               ó   € V ^8„  d   QhRR/# r9  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ½  s   € ÷ @ñ @�Cñ @rË   c                 ór   € \         P                  ! \        4      P                  4       P	                  RR4      # )zQCurrent UTC time as an ISO-8601 string with a ``Z`` suffix (last_refresh format).ú+00:00ÚZ)r	   r}  r   r~  r^  rÇ   rË   rÉ   Ú
_utc_now_zr  ½  s'   € ä�<Š<œÓ×&Ñ&Ó(×0Ñ0°¸3Ó?Ð?rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   rJ  r   rÅ   zOptional[float]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Â  s   € ÷ ñ  ð ¨ñ rË   c                óf  € \        V \        4      '       d   V P                  4       MR pV'       g   R# VP                  R4      '       d   VRR R,           p \        P
                  ! V4      pTP                  f   TP                  \        R7      pTP                  4       #   \         d     R# i ; i)rÍ   Nr
  r	  )Útzinfoéÿÿÿÿ)r+  rÄ   rÜ   rZ  r	   ÚfromisoformatrÖ   r  r^  r   Ú	timestamp)rJ  Útextrß   s   &  rÉ   Ú_parse_iso_timestampr  Â  s”   € Ü& u¬c×2Ò2ˆ5�;‰;Œ=¸€DßÙØ‡}�}�S×ÒØ�C�Rˆy˜8Õ#ˆðÜ×'Ò'¨Ó-ˆð ‡}�}ÒØ—‘¤s�Ó+ˆØ×ÑÓÐøô	 ô Úðús   ÁB! Â!B0Â/B0c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   Úexpires_at_isor   Úskew_secondsrf  rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ñ  s&   € ÷ Rñ R ð R°Cð R¸Dñ RrË   c                ón   € \        V 4      pVR J ;'       g     V\        P                  ! 4       V,           8*  # r*  )r  rL  )r  r  Úexpires_epochs   && rÉ   Ú_is_expiringr  Ñ  s/   € Ü(¨Ó8€MØ˜DÐ ×QÐQ M´d·i²i³kÀLÕ6PÑ$QÐQrË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   Úverifyr   rÅ   rë   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ö  s   € ÷ cñ c 3ð c¨>ñ crË   c                óD   € RV RJ R\        V \        4      '       d   V /# R/# )zAPersistable ``tls`` block derived from an httpx ``verify`` value.ÚinsecureFÚ	ca_bundleN)r+  rÄ   )r  s   &rÉ   Ú_tls_state_from_verifyr  Ö  s+   € à˜ %˜¨Ä
È6ÔSV×@WÒ@W°fÐbÐbÐ]aÐbÐbrË   Údefault_codec          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
rÂ   r‡  rÄ   r­  r¾   Úreasonr   rz  rÅ   rë   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Û  s4   € ÷ -ñ -Øð-Ø#ð-Ø03ð-ØCPð-àñ-rË   c               óÄ   € RT R\        V4      RTRRRVf   VP                  MVP                  ;'       g    TR\        P                  ! \        4      P                  4       /# )zQThe ``last_auth_error`` record persisted when dead OAuth material is quarantined.r‡  r�  r"  r¯  Tr°  Úat)rÄ   r°  r	   r}  r   r~  )r‡  r­  r"  r   s   &&$$rÉ   Ú_last_auth_error_markerr%  Û  sX   € ð
 	�H˜i¬¨U«°X¸vÐGYÐ[_Ø˜lÒ2�—
’
¸¿¹×9SÐ9SÀ|ØŒh�lŠlœ3Ó×)Ñ)Ó+ð-ð -rË   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	rÂ   rˆ  rë   r‡  rÄ   r¤  r¾   rÅ   r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   è  s/   € ÷ Xñ X¨ð XÀ#ð XÈIð XÐZ^ñ XrË   c                óf   € \          F  pV P                  VR4       K  	  \        WRRR7      V R&   R# )z²Strip dead tokens from a flat OAuth state after a terminal runtime refresh failure so
subsequent calls fail fast without a network retry (mirrors the Nous / xAI / Codex pattern).NÚruntime_refresh_failureÚrefresh_failed)r"  r   Úlast_auth_error)Ú_FLAT_OAUTH_TOKEN_KEYSrá  r%  )rˆ  r‡  r¤  Ú_ks   &&& rÉ   Ú_quarantine_flat_oauth_stater-  è  s6   € ÷ %ˆØ�	‰	�"�dÖñ %ä6ØÐ7ÐFVô X€EÐ
ÓrË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   Ú
expires_inr   rÅ   rf  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ñ  s   € ÷ ñ  Cð ¨Cñ rË   c                óR   €  \        ^ \        V 4      4      #   \         d     ^ # i ; i)r8  )rN  rf  rÖ   )r/  s   &rÉ   Ú_coerce_ttl_secondsr1  ñ  s*   € ðÜ�1”c˜*“oÓ&Ð&øÜô Úðús   ‚ —&¥&c               ó    € V ^8„  d   QhRRRR/# )rÂ   rJ  r   rÅ   rz  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ø  s   € ÷ ñ ˜cð  mñ rË   c                óˆ   € \        V \        4      '       d    V P                  4       P                  R 4      MRpT;'       g    R# )rÛ   rÍ   N)r+  rÄ   rÜ   rÕ   )rJ  ri  s   & rÉ   Ú_optional_base_urlr4  ø  s2   € Ü+5°e¼S×+AÒ+Aˆe�k‰k‹m×"Ñ" 3Ô'Àr€GØ�?ˆ?�dÐrË   úfrozenset[str]Ú_NOUS_PORTAL_ALLOWED_HOSTSzdict[str, tuple[float, str]]Ú_RESOLVE_TOKEN_CACHEç      @r<  ç      .@r  r  Úrefresh_skew_secondsc          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# ©rÂ   r<  r=  r  zOptional[bool]r  rz  r:  rf  rÅ   rÄ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s>   € ÷ 4ñ 4àð4ð ð4ð ð	4ð
 ð4ð
 GJñ4rË   c                ó4   a aaa€ ^ RI Hp V! VVVV 3R l4      # )a  Refresh-aware Nous Portal token for managed tool gateways, connectors and account reads, never
the free model: a guest gets a live held token, else a connectors-only mint NAS never challenges.
Only a NAS from before hermes-portal#1516 challenges that mint; it is worked here as before.)Úrun_with_challengec                 ó"   <€ \        SSS SR 7      # ))r<  r  r  r:  )Ú_resolve_nous_access_token)r  r  r:  r<  s   €€€€rÉ   rÓ  Ú+resolve_nous_access_token.<locals>.<lambda>  s   ø€ Ô&@Ø'°(ÀiØ1õ'3rË   )Úhermes_cli.anon_challenger>  )r<  r  r  r:  r>  s   dddd rÉ   Úresolve_nous_access_tokenrC    s   û€ õ =Ù÷ 3ó 4ð 4rË   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R
/# r<  rÇ   )rÈ   s   "rÉ   rÊ   rÊ     sC   € ÷ M0ñ M0àðM0ð ðM0ð ð	M0ð
 ðM0ð
 #&ñM0rË   c                óô  aaaaa€ V'       * ;'       d    VR J o\        4       oS'       df   \        ;_uu_ 4        \        P                  S4      pR R R 4       Xe6   \        P
                  ! 4       V^ ,          ,
          \        8  d
   V^,          # R VV3R llp\        R4      ;_uu_ 4       w  oooS'       g   \        RRRR7      h\        S4      p\        SP                  R4      ;'       g    \        4      p\        WSR	7      pVVV3R
 lp	\        V R,           \        4      p
\        V
R7      ;_uu_ 4        ^ RIHpHpHp V! S4      '       d²   V! SVR7      ;p'       d   V! V4      uuR R R 4       uuR R R 4       # \(        P*                  ! \(        P,                  ! T ;'       g    R4      RR/VR7      ;_uu_ 4       pV! SVRR7      pR R R 4       V	! 4        \/        S4       V! X4      uuR R R 4       uuR R R 4       # \1        S4      pSP                  R4      pSP                  R4      p\3        V\        4      '       d	   V'       g   \        RRRR7      h\5        SP                  R4      V4      '       g,   V'       d   V	! 4        V! V4      uuR R R 4       uuR R R 4       # \3        V\        4      '       d	   V'       g   \        RRRR7      h\(        P*                  ! \(        P,                  ! T ;'       g    R4      RR/VR7      ;_uu_ 4       p\7        VSSVVVRV	R7      pR R R 4       \9        SXV4       VSR&   VSR&   \;        V4      SR&   V	! 4        \/        S4       V! SR,          4      uuR R R 4       uuR R R 4       #   + '       g   i     ELG; i  + '       g   i     ELÛ; i  + '       g   i     L’; i  + '       g   i     M; i R R R 4       R #   + '       g   i     R # ; i) Nc               ó    € V ^8„  d   QhRRRR/# )rÂ   r¡  rÄ   rÅ   rÇ   )rÈ   s   "rÉ   rÊ   Ú0_resolve_nous_access_token.<locals>.__annotate__+  s   € ÷ ñ �Sð ˜Sñ rË   c                ó®   <€ S'       d8   \         ;_uu_ 4        \        P                  ! 4       V 3\        S&   R R R 4       V # V #   + '       g   i     T # ; ir*  )Ú_RESOLVE_TOKEN_CACHE_LOCKrL  rM  r7  )r¡  rå  Úmemoables   &€€rÉ   Ú_memoÚ)_resolve_nous_access_token.<locals>._memo+  s?   ø€ ßß*Ö*Ü37·>²>Ó3CÀUÐ2KÔ$ YÑ/÷ +àˆˆuˆ÷ +Ö*àˆús   ˜AÁA	rü   z&Hermes is not logged into Nous Portal.Únous_auth_missingT)Úreloginrè   )r  r  Ú
auth_statec                 ó    <€ \        S R SS4      # )rü   )r¦  )rz  rˆ  Ústate_source_paths   €€€rÉ   rÓ  Ú,_resolve_nous_access_token.<locals>.<lambda>7  s   ø€ Ô8Ø˜ Ð'8ô:rË   r8  )r<  )Úheld_connectors_tokenÚis_guest_stateÚrefresh_guest_state)r  r9  ÚAcceptzapplication/json)ÚtimeoutÚheadersr  Ú
connectors)Úpurposer—  rÍ  z,No access token found for Nous Portal login.Únous_auth_missing_access_tokenÚ
expires_atz2Session expired and no refresh token is available.Únous_auth_missing_refresh_tokenÚ$managed_access_token_refresh_failure)Úclientrz  rˆ  ræ   rè   rÍ  r"  Úpersistræ   Útls)r   rI  r7  rq  rL  rM  Ú_RESOLVE_TOKEN_CACHE_TTL_Sr•  r¿   rK   rÄ   rœ   r2   rN  r™   rM   ræ  rS  rT  rU  rÀ   ÚClientÚTimeoutrZ   rE   r+  r  rT   r?   r  )r<  r  r  r:  ræ  rK  ræ   rè   r  r`  Úlock_timeoutrS  rT  rU  r—  r_  ÚmintedÚmerged_sharedrÍ  Ú	refreshedrz  rå  rJ  rˆ  rQ  s   $$$$                @@@@@rÉ   r@  r@    sY  ü€ ð Œ|×1Ð1 	¨TÐ 1€HÜÓ!€Ißß&Ö&Ü)×-Ñ-¨iÓ8ˆF÷ 'àÒ¤4§>¢>Ó#3°f¸QµiÕ#?ÔC]Ô"]Ø˜!•9Ð÷ñ ô 
% V×	,Ô	,Ñ0V°¸UÐDUßÜÐDÐFYÐcgÔhÐhÜ/°Ó6ˆÜ˜Ÿ	™	 +Ó.×HÐHÔ2HÓIˆ	Ü ¨(ÐTYÔZˆö:ˆô ˜?¨SÕ0Ô2KÓLˆÜ$°\×BÖBßgÑgÙ˜e×$Ò$á#8¸ÐMaÔ#bÐb�<ÖbÙ  Ó.÷ CÑB÷ 
-Ò	,ô  —\’\¬%¯-ª-¸×8OÐ8OÈ4Ó*PØ+3Ð5GÐ*HÐQW÷Yõ YØ\bÙ0°¸ÈÔU�F÷Yñ ”	Ü(¨Ô/Ù˜V“}÷ CÑB÷ 
-Ò	,ô. ;¸5ÓAˆMØ Ÿ9™9 ^Ó4ˆLØ!ŸI™I oÓ6ˆMÜ˜l¬C×0Ò0¿ÜØBÐDdÐnrôtð tô   §	¡	¨,Ó 7Ð9M×NÒNß Ù”Iñ ˜\Ó*÷5 CÑB÷ 
-Ò	,ôL ˜m¬S×1Ò1¿ÜØHÐJkØ ô"ð "ô —’¤e§m¢m°O×4KÐ4KÀtÓ&LØ'/Ð1CÐ&DÈV÷Uõ UØX^Ü7Ø!¨jÀÐWfØ'°}ØAÈ7ôT�	÷Uô )¨°	¸=ÔIØ'6ˆEÐ#Ñ$Ø!*ˆE�+ÑÜ1°&Ó9ˆE�%‰LÙŒIÜ$ UÔ+Ù˜˜~Õ.Ó/÷] CÑB÷ 
-Ò	,÷ '×&Ð&ú÷6Y÷ Yð Yú÷6U÷ Uú÷C C×BúÐB÷ 
-×	,×	,Ò	,ús±   ¹NÂ-AO&Ã0AO&Ä;*O	Å&O	Å-
O&Æ(O	Æ+O	ÇN!Ç!O	Ç0
O&ÈA
O	É6O	ÊO	Ê
O&Ê*O	Ë6O	Ë?O	ÌN5Ì+AO	Í8
O&ÎN	Î!N2Î,	O	Î5OÏ O	ÏOÏO&Ï&O7	z<Optional[tuple[float, str, Optional[float], dict[str, Any]]]Ú_nous_auth_status_cachez)Optional[tuple[str, int, dict[str, Any]]]rÞ  c               ó   € V ^8„  d   QhRR/# )rÂ   rÅ   ztuple[str, Optional[float]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   y  s   € ÷ .ñ .Ð9ñ .rË   c                 óž   € \        4       p  \        V 4      V P                  4       P                  3#   \         d    \        T 4      R 3u # i ; ir*  )rÐ  rø  rà  Úst_mtimerÖ   )ra  s    rÉ   Ú_auth_file_cache_keyrm  y  sK   € ÜÓ!€Ið.Ü˜YÓ'¨¯©Ó)9×)BÑ)BÐBÐBøÜô .Ü˜YÓ'¨Ð-Ò-ð.ús   Œ$1 ±AÁAc               ó   € V ^8„  d   QhRR/# r‚  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   �  s   € ÷ #ñ #¨4ñ #rË   c                 ó
   € Rs R# )zµClear the get_nous_auth_status() memo (for code paths that mutate Nous auth state without
touching auth.json, e.g. tests; login/logout invalidate via the mtime check automatically).N)ri  rÇ   rË   rÉ   Ú!invalidate_nous_auth_status_cacherp  �  s
   € ð #ÒrË   c               ó   € V ^8„  d   QhRR/# rØ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ˆ  s   € ÷ ñ ˜nñ rË   c                 óþ   € \         P                  ! 4       p \        4       w  r\        pVe:   VR,          W38X  d+   W^ ,          ,
          \        8  d   \        V^,          4      # \        4       pWV\        V4      3sV# )a	  Status snapshot for Nous auth, memoised ~15s keyed on the auth.json mtime.

Prefers the auth-store provider state (the live source of truth for refresh) and validates it by
resolving runtime credentials so revoked refresh sessions do not show up as a healthy login.:é   é   N)rL  rM  rm  ri  Ú_NOUS_AUTH_STATUS_CACHE_TTLrö   rA   )r}  Úauth_file_keyÚmtimeræ  Ústatuss        rÉ   Úget_nous_auth_statusry  ˆ  so   € ô �.Š.Ó
€CÜ/Ó1Ñ€MÜ$€FØÒ˜v c�{¨}Ð.DÔDØ˜a•y•Ô$?Ô?Ü�F˜1•I‹ÐÜ&Ó(€FØ"°5¼$¸v»,ÐGÐØ€MrË   )Úfrozenc                  ó„   € ] tR tRt$ RtR]R&   R]R&   R]R&   ]! 4       tR]R&   R	tR
]R&   R R lt	R R lt
R R ltRtR# )ÚOAuthProviderFlowi™  zõPer-provider OAuth plumbing, keyed by provider id in ``OAUTH_PROVIDER_FLOWS``.

Callables are named (strings) and looked up in this module at call time so
``monkeypatch.setattr("hermes_cli.auth.resolve_codex_runtime_credentials", ...)`` applies.rÄ   rn  Ú
resolve_fnÚ	status_fnr5  Úterminal_refresh_codesFrÆ   Úlogout_from_configc               ó    € V ^8„  d   QhRRRR/# )rÂ   Úkwargsr   rÅ   rë   rÇ   )rÈ   s   "rÉ   rÊ   ÚOAuthProviderFlow.__annotate__§  s   € ÷ 4ñ 4 ð 4¨ñ 4rË   c                	óD   € \        4       V P                  ,          ! R/ VB # )NrÇ   )Úglobalsr}  )Úselfr‚  s   &,rÉ   rß  ÚOAuthProviderFlow.resolve§  s   € Ü‹y˜Ÿ™Ö)Ñ3¨FÑ3Ð3rË   c               ó   € V ^8„  d   QhRR/# rØ  rÇ   )rÈ   s   "rÉ   rÊ   rƒ  ª  s   € ÷ +ñ +˜ñ +rË   c                	óB   € \        4       V P                  ,          ! 4       # r*  )r…  r~  )r†  s   &rÉ   rx  ÚOAuthProviderFlow.statusª  s   € Ü‹y˜Ÿ™Ö(Ó*Ð*rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   r¤  rÖ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rƒ  ­  s   € ÷ Xñ X¨Yð X¸4ñ XrË   c                	óà   € \        V\        4      ;'       dX    VP                  V P                  8H  ;'       d7    VP                  V P
                  9   ;'       d    \        VP                  4      # r*  )r+  r¾   r‡  rn  r°  r  rÆ   r¯  )r†  r¤  s   &&rÉ   Úis_terminal_refresh_errorÚ+OAuthProviderFlow.is_terminal_refresh_error­  sg   € ä�sœIÓ&÷ Wð W¨3¯<©<¸4×;KÑ;KÑ+K÷ Wð WØ—‘˜D×7Ñ7Ñ7÷Wð WÜ<@À×AUÑAUÓ<Vð	XrË   rÇ   N)rð   rñ   rò   ró   rô   rõ   Ú	frozensetr  r€  rß  rx  r�  r÷   rÇ   rË   rÉ   r|  r|  ™  sJ   ‡ ñbð ÓØƒOØƒNÙ-6«[Ð˜NÓ8ð  %Ð˜Ó$õ4õ+÷Xñ XrË   r|  r`   ry  )r  r€  r�   Úget_codex_auth_statusÚcodex_refresh_failedÚ codex_auth_missing_refresh_tokenr|   Úget_xai_oauth_auth_statusÚxai_refresh_failedÚxai_auth_missing_refresh_tokenr–   r•   rn   Úget_minimax_oauth_auth_statuszdict[str, OAuthProviderFlow]ÚOAUTH_PROVIDER_FLOWSc               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   r¤  rÖ   r‡  rÄ   rÅ   rÆ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Í  s&   € ÷ Iñ I Ið I¸ð IÀñ IrË   c                ó:   € \         V,          P                  V 4      # )zDTrue when retrying the same *provider* refresh token cannot succeed.)r—  r�  )r¤  r‡  s   &&rÉ   Ú_is_terminal_refresh_errorrš  Í  s   € ä Õ)×CÑCÀCÓHÐHrË   )r‡  c               ó   € V ^8„  d   QhRR/# )rÂ   rÅ   r†  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ø  s   € ÷ 0ñ 0Ð)Añ 0rË   c                 ó"  € \        4       p V '       g   R # RRR\        \        4       4      RV P                  R4      RRRRV P                  R	4      ;'       g    R
 2RRR\        RV P                  R4      ;'       g    RRV P                  R4      /	# )Nrå  Trz  Úlast_refreshÚ	auth_moder½  ry  úpool:ÚlabelÚunknownÚrate_limitedÚ
error_coder­  r�  zCCodex provider quota exhausted; retry after the usage limit resets.Úreset_at)r€   rÄ   rÐ  rq  r½   )Ú
rate_limits    rÉ   Ú_codex_pool_rate_limited_statusr¦  Ø  s‘   € Ü.Ó0€JßÙà�T˜<¬¬_Ó->Ó)?Ø˜
Ÿ™ ~Ó6¸ÀYØ�E˜*Ÿ.™.¨Ó1×>Ð>°YÐ?Ð@À.ÐRVØÔ-Ø�*—.‘. Ó+÷ [ð [ØZØ�J—N‘N :Ó.ð0ð 0rË   c               ó   € V ^8„  d   QhRR/# rØ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   æ  s   € ÷ ñ ˜~ñ rË   c                 óê   € \        R\        RR \        R7      p \        V P	                  R4      ;'       g    R4      P                  R4      '       d!   ^ RIHp V! V P	                  R	4      4      V R	&   V # )
zªStatus snapshot for Codex auth (pool first, then legacy provider state).

Read-only by contract: status/doctor must never adopt, refresh or persist a credential (#68004).rþ   r½  c                 ó   € \        R R7      # )T)Ú	read_only)r�   rÇ   rË   rÉ   rÓ  Ú'get_codex_auth_status.<locals>.<lambda>ì  s
   € Ô9ÀDÕIrË   )Úis_expiringrž  rß  Úon_pool_missry  rÍ   rŸ  )Ú_codex_pool_route_base_urlrÃ   )rO   r}   r¦  rÄ   rq  rY  Úhermes_cli.auth_codexr®  )rx  r®  s     rÉ   r�  r�  æ  se   € ô &ØÔ$CÈyÙIÜ4ô6€Fô ˆ6�:‰:�hÓ×%Ð% 2Ó&×1Ñ1°'×:Ò:åDÙ7¸¿
¹
À:Ó8NÓOˆˆzÑØ€MrË   c               ó   € V ^8„  d   QhRR/# rØ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   õ  s   € ÷ Zñ Z >ñ ZrË   c                 ó*   € \        R \        RR R7      # )r   rý   c                 ó   € \        R R7      # )F)Úrefresh_if_expiring)r|   rÇ   rË   rÉ   rÓ  Ú+get_xai_oauth_auth_status.<locals>.<lambda>ú  s   € Ô=ÐRWÕXrË   )r¬  rž  rß  )rO   rt   rÇ   rË   rÉ   r“  r“  õ  s   € ô $ØÔ!>ÐJ]ÙXôZð ZrË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   r�  râ   rÅ   rÄ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ý  s   € ÷ 	_ñ 	_ Nð 	_°sñ 	_rË   c                óê  € V P                   R 8X  d¡   ^ RIHp \        4       P	                  R4      p\        V\        4      '       dl   T! \        VP	                  R4      ;'       g    R4      4      R 8X  d=   \        VP	                  R4      ;'       g    R4      P                  4       pV'       d   V# V P                  '       d0   \        P                  ! V P                  R4      P                  4       # R# )r  )Únormalize_providerr†  r‡  rÍ   rÃ   )rã   ri  r·  r3  rq  r+  rö   rÄ   rÜ   rï   rÊ  rÒ  )r�  r·  r†  Úconfigured_urls   &   rÉ   Ú_provider_env_base_urlr¹  ý  s´   € Ø‡z�z�XÔÝ;äÓ!×%Ñ% gÓ.ˆÜ�eœT×"Ò"Ñ'9¼#¸e¿i¹iÈ
Ó>S×>YÐ>YÐWYÓ:ZÓ'[Ð_gÔ'gÜ  §¡¨:Ó!6×!<Ð!<¸"Ó=×CÑCÓEˆNßØ%Ð%Ø>E×>V×>VÐ>VŒ2�9Š9�W×-Ñ-¨rÓ2×8Ñ8Ó:Ð^Ð\^Ð^rË   c               ó    € V ^8„  d   QhRRRR/# ©rÂ   rn  rÄ   rÅ   rë   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   	  s   € ÷ 7ñ 7¨Sð 7°^ñ 7rË   c                óÈ  € \        V 4      pV'       d   VP                  R8w  d   RR/# \        W4      w  r#\        V4      pV R9   d   \	        W!P
                  V4      pMT;'       g    VP
                  pRpV R8X  d&   \        V4      pV'       * ;'       d    \        V4      p\        V4      ;'       g    TpRTRT RVP                  RT;'       g    V'       d   RMR	R
VRV/# )z<Status snapshot for API-key providers (z.ai, Kimi, MiniMax).rø   Ú
configuredFr  r‡  rä   Ú
key_sourceúlocal-offlinerÍ   rÃ   rå  >   r	  r
  )
r­  rå   r«  r¹  r!   rç   rà   rØ   rÆ   rä   )rn  r�  rø   r¾  Úenv_urlrÃ   Úactual_local_noauthr½  s   &       rÉ   Úget_api_key_provider_statusrÂ  	  sã   € ä˜{Ó+€Gß�g×'Ñ'¨9Ô4Ø˜eÐ$Ð$Ü:¸;ÓPÑ€GÜ$ WÓ-€GØÐ7Ô7Ü)¨'×3MÑ3MÈwÓW‰à×8Ð8˜g×8Ñ8ˆØÐØ�hÔÜ,¨XÓ6ˆØ")œk×PÐPÔ.FÀxÓ.PÐÜ�g“×5Ð5Ð"5€Jà�j *¨k¸6À7Ç<Á<Ø�j×TÐT×8K¡_ÐQSØ�H˜k¨:ð7ð 7rË   c               ó$   € V ^8„  d   QhRRRRRR/# )rÂ   rn  rÄ   Úresolved_commandrz  rÅ   útuple[bool, Optional[str]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ     s'   € ÷ 
Yñ 
Y°ð 
YÈð 
YÐZtñ 
YrË   c                óF   € V R8X  d   \        4       # V'       d   RRV 23# R# )aG  Best-effort POSITIVE evidence ``(verified, source)`` that an external-process CLI is authed.

False means "not verifiable from here", NOT "signed out". Subprocess-free (spawning the CLI from
status endpoints/pickers re-creates the cold-start stall copilot_auth.py avoids). Generic evidence
for any external-process profile is its binary resolving: the subprocess owns real auth and Hermes
has nothing else to inspect, so out-of-tree ACP rows pass credential-gated surfaces (Desktop
``explicit_only`` picker) like the bundled one, whose CLI additionally exposes readable token stores.r  Tz	command: ©FN)Ú_copilot_acp_auth_evidence)rn  rÄ  s   &&rÉ   Ú_external_process_auth_evidencerÉ    s0   € ð �mÔ#Ü)Ó+Ð+ß5EˆD�IÐ.Ð/Ð0Ð1ÐXÈ=ÐXrË   c               ó   € V ^8„  d   QhRR/# )rÂ   rÅ   rÅ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ,  s   € ÷ !ñ !Ð$>ñ !rË   c                 óH  €  ^ RI Hp Hp V  FP  p\        P                  ! VR4      P                  4       pV'       g   K2  V! V4      ^ ,          '       g   KI  RRV 23u # 	   \        P                  P                  R4      p\        P                  P                  V4      '       Ed    \        VRR	R
R7      ;_uu_ 4       pRP                  R VP                  4       P                  4        4       4      pRRR4       XP                  4       '       d   \         P"                  ! V4      M/ P%                  R4      p\'        V\(        4      '       dY   \*        ;QJ d*    R VP-                  4        4       F  '       g   K   RM	  RM! R VP-                  4        4       4      '       d   R# R Ft  p	 \        P                  P                  T	4      p
\        P                  P                  T
4      '       d-   \        P                  P/                  T
4      ^8”  d   RT	3u # Kt  Kv  	  R#   \         d"   p\        P                  RT4        Rp?ELèRp?ii ; i  + '       g   i     ELg; i  \         d!   p\        P                  RT4        Rp?LåRp?ii ; i  \0         d     Kù  i ; i)zaCopilot CLI token stores readable without spawning it (env tokens, plaintext config, hosts.json).)ÚCOPILOT_ENV_VARSÚvalidate_copilot_tokenrÍ   Tzenv: z/copilot-acp env token evidence check failed: %sNú~/.copilot/config.jsonr-  r  Úignorer   r0  c              3  ór   "  € T F-  qP                  4       P                  R 4      '       d   K)  Vx € K/  	  R# 5i)z//N)ÚlstriprY  )r,  Úlines   & rÉ   r.  Ú-_copilot_acp_auth_evidence.<locals>.<genexpr>=  s)   é € ð  cÙ%;˜TÇ;Á;Ã=×C[ÑC[Ð\`×Ca—D’DÓ%;ùs   ‚&7­
7ÚcopilotTokensc              3  ór   "  € T F-  p\        V\        4      ;'       d    VP                  4       x € K/  	  R # 5ir*  )r+  rÄ   rÜ   r>  s   & rÉ   r.  rÓ  @  s,   é € ð 0KÙ:I°Q”
˜1œcÓ"×0Ð0 q§w¡w£yÔ0»/ùs   ‚7ž7Fz0copilot-acp CLI config evidence check failed: %s)TrÎ  )z#~/.config/github-copilot/hosts.jsonz"~/.config/github-copilot/apps.jsonrÇ  )r™  rÌ  rÍ  rÊ  rÒ  rÜ   rÖ   r|  rl  rÝ   Ú
expanduserÚisfilerK  r~  Úreadr�  rh  ri  rq  r+  rö   ræ  rR  Úgetsizerô  )rÌ  rÍ  r¥  ro  r¤  Ú
cli_configÚfhrm  ÚtokensÚ	cred_pathÚexpandeds              rÉ   rÈ  rÈ  ,  s  € ðMßTÛ'ˆGÜ—)’)˜G RÓ(×.Ñ.Ó0ˆCß‰sÑ-¨cÓ2°1×5Ö5Ø˜u W IÐ.Ð.Ò.ñ (ðNÜ—W‘W×'Ñ'Ð(@ÓAˆ
Ü�7‰7�>‰>˜*×%Ó%Ü�j #°ÀH×MÕMÐQSØ—i‘iñ  cØ%'§W¡W£Y×%9Ñ%9Ô%;ó có c�÷ Nð *-¯©¯ª”d—j’j ”o¸"×AÑAÀ/ÓRˆFÜ˜&¤$×'Ò'¯C«Cñ 0KØ:@¿-¹-¼/ó0K¯C¯CªCñ 0KØ:@¿-¹-¼/ó0K÷ -Kò -Kà5Ð5ó cˆ	ð	Ü—w‘w×)Ñ)¨)Ó4ˆHÜ�w‰w�~‰~˜h×'Ò'¬B¯G©G¯O©O¸HÓ,EÈÔ,IØ˜Y�Ò&ñ -JÑ'ñ cð Ðøô1 ô MÜ�‰ÐFÈ×LÒLûðMú÷ N×MÐMûô ô NÜ�‰ÐGÈ×MÑMûðNûô ô 	Úð	ús‹   ‚7H! ¾H! ÁH! ÁH! Á!AI$ Â&I$ Â=5IÃ2I$ ÄAI$ ÅI$ Å:(I$ Æ#I$ Æ+A+JÈ!IÈ,IÉIÉI!	É	I$ É$JÉ/J
Ê
JÊJ!Ê J!c               ó    € V ^8„  d   QhRRRR/# )rÂ   r�  râ   rÅ   z:tuple[str, list[str], str, Optional[str], tuple[str, ...]]rÇ   )rÈ   s   "rÉ   rÊ   rÊ   P  s    € ÷ `ñ `Øð`Ø Zñ`rË   c                óš  € \        V 4      ;'       g    V P                  p ^ RIHp V! V P                  4      p\        \        VRR4      ;'       g    R4      p\        \        VRR4      ;'       g    R4      p\        R R V 4        4       R4      ;'       g!    \        \        VRR4      ;'       g    R4      pV'       d&   \        P                  ! VR4      P                  4       MRpV'       d   \        P                  ! V4      M\        \        VR	R4      ;'       g    . 4      p^ R
IHp	 WhW! V4      V3#   \
         d    Rp ELi ; i)a  ``(command, args, base_url, resolved_command, command_env_vars)`` for an ACP provider.

Launch details come from the provider's own profile (copilot-acp: HERMES_COPILOT_ACP_COMMAND /
COPILOT_CLI_PATH / HERMES_COPILOT_ACP_ARGS), so out-of-tree providers describe their binary.)Úget_provider_profileNÚprocess_command_env_varsÚprocess_args_env_varrÍ   c              3  ó8   "  € T F  q'       g   K  Vx € K  	  R # 5ir*  rÇ   r>  s   & rÉ   r.  Ú)_external_process_spec.<locals>.<genexpr>^  s   é € Ð^Ñ X˜1Ó\]—Q’QÓ XùrA  c              3  ól   "  € T F*  p\         P                  ! VR 4      P                  4       x € K,  	  R# 5irC  )rÊ  rÒ  rÜ   )r,  rD  s   & rÉ   r.  rå  ^  s)   é € Ð XÑGWÀ¤§¢¨3°Ó!3×!9Ñ!9×!;Ð!;ÓGWùs   ‚24Úprocess_commandÚprocess_args)Ú resolve_external_process_commandrÇ   )r¹  rç   r^  rá  rã   rÖ   rí   r   rÄ   rF  rÊ  rÒ  rÜ   Úshlexr%  rÁ  Ú hermes_cli.auth_external_processré  )
r�  rÃ   Ú_get_provider_profileÚprofileÚcommand_env_varsÚargs_env_varÚcommandÚraw_argsÚargsré  s
   &         rÉ   Ú_external_process_specró  P  s'  € ô & gÓ.×LÐL°'×2LÑ2L€HðÝKÙ'¨¯
©
Ó3ˆô œW WÐ.HÈ"ÓM×SÐSÐQSÓTÐÜ”w˜wÐ(>ÀÓC×IÐIÀrÓJ€LÜÑ^Ñ XÑGWÔ XÓ^Ð`bÓc÷ Eð EÜ”g˜gÐ'8¸"Ó=×CÐCÀÓDð ç6BŒr�yŠy˜ rÓ*×0Ñ0Ô2È€Hß$,Œ5�;Š;�xÔ ´$´w¸wÈÐXZÓ7[×7aÐ7aÐ_aÓ2b€DÝQØ˜(Ð$DÀWÓ$MÐO_Ð_Ð_øô ô Ø‹ðús   ¡D9 Ä9E
Å	E
c               ó    € V ^8„  d   QhRRRR/# r»  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   f  s   € ÷ \ñ \°cð \¸nñ \rË   c                ó  € \        V 4      pV'       d   VP                  R8w  d   RR/# \        V4      w  r#rEp\        T;'       g    VP	                  R4      4      p\        W4      w  r‰RVRV RVP                  RVRVR	VR
VRVRVRV	/
# )zñStatus snapshot for providers that run a local subprocess.

``configured``/``logged_in`` are structural (executable resolves or TCP endpoint set): the
subprocess owns real auth. ``auth_verified``/``auth_source`` carry positive evidence only.r  r½  Fú
acp+tcp://r‡  rä   rð  rò  rÄ  rÃ   rå  Úauth_verifiedÚauth_source)r­  rå   ró  rÆ   rY  rÉ  rä   )
rn  r�  rð  rò  rÃ   rÄ  rW  Ú	availabler÷  rø  s
   &         rÉ   Ú$get_external_process_provider_statusrú  f  s¥   € ô
 ˜{Ó+€Gß�g×'Ñ'Ð+=Ô=Ø˜eÐ$Ð$Ü3IÈ'Ó3RÑ0€G�8¨qÜÐ%×JÐJ¨×)<Ñ)<¸\Ó)JÓK€IÜ!@ÀÓ!_Ñ€Mà�i ¨[¸&À'Ç,Á,ÐPYÐ[bØ�Ð(Ð*:¸JÈØ�Y °ÀÈ{ð\ð \rË   c               ó    € V ^8„  d   QhRRRR/# )rÂ   rr  rÄ   rÅ   rë   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   w  s   € ÷ Xñ X Sð X¨^ñ XrË   c                óX   €  ^ RI Hp RV! 4       RV /#   \         d    RRRT RR/u # i ; i)uA   AWS SDK providers (Bedrock) â€” check via boto3 credential chain.rü  rå  r‡  Fr­  zboto3 not installed)r  rý  rÖ  )rr  rý  s   & rÉ   Ú_get_aws_sdk_auth_statusrý  w  sC   € ðXÝ=ØÑ0Ó2°JÀÐGÐGøÜô XØ˜U J°¸ÐAVÐWÒWðXús   ‚ “)¨)c               ó    € V ^8„  d   QhRRRR/# r¾  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   €  s   € ÷  ñ   ð  ¸.ñ  rË   c                ó¤  € T ;'       g    \        4       ;'       g    RP                  4       P                  4       pV'       g   RR/# \        P	                  V4      pV'       d   \        4       V,          ! 4       # \        V4      pV'       dB   VP                  \        9   d-   \        4       \        VP                  ,          ,          ! V4      # RR/# )aP  Generic auth status dispatcher: bespoke builders (``OAUTH_PROVIDER_FLOWS`` plus Azure
Foundry) first, then the registry ``auth_type`` so a whole provider class (e.g. every
external-process ACP backend) gets a real status. Builders are looked up by NAME at call time so
tests that patch ``hermes_cli.auth.get_*_auth_status`` still apply.rÍ   rå  F)	r2  rÜ   rÔ   Ú_BESPOKE_STATUS_FUNCTIONSrq  r…  r­  rå   Ú_STATUS_BY_AUTH_TYPE)rn  rr  Ústatus_fn_namer�  s   &   rÉ   rç  rç  €  s¤   € ð
 ×8Ð8Ô0Ó2×8Ð8°b×?Ñ?ÓA×GÑGÓI€FßØ˜UÐ#Ð#Ü.×2Ñ2°6Ó:€NßÜ‹y˜Ö(Ó*Ð*Ü˜vÓ&€Gß�7×$Ñ$Ô(<Ô<Ü‹yÔ-¨g×.?Ñ.?Õ@ÖAÀ&ÓIÐIØ˜ÐÐrË   Ú_get_azure_foundry_auth_statusr   rú  rÂ  rý  r5  r  c               ó   € V ^8„  d   QhRR/# rØ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ÿ  s   € ÷ .ñ .¨ñ .rË   c                 óö  € RR/p  ^ RI HpHp V! 4       p\	        V\
        4      '       d   VP                  R4      MRp\	        V\
        4      '       g   / p\        VP                  R4      ;'       g    R4      P                  4       P                  4       ;'       g    RpWPR&   \        VP                  R4      ;'       g    R	4      P                  4       V R&   VR
8X  d—    ^ RI
HpHpHp V! 4       p	\	        VP                  R4      \
        4      '       d
   VR,          M/ p
VP                  W§R7      pT P                  Y›P                   RR\#        V	4      V	'       d   RMR\%        R4       R2R7       V #  X! R4      ;'       g    R	p\+        V4      V R&   V #   \         d    / p EL”i ; i  \         d   pRT R&   RT 2T R&    Rp?T # Rp?ii ; i  \         d    \&        P(                  ! RR	4      p Lni ; i)uý   Structural auth status for Azure Foundry.

``entra_id``: ``azure-identity`` importable â€” never invokes the Entra credential chain (keeps
CLI startup flat; ``hermes doctor`` runs the live probe). ``api_key`` (default): usable
``AZURE_FOUNDRY_API_KEY``.r‡  r'  )r…  r<  r†  Nrž  rø   rÃ   rÍ   Úentra_id)ÚEntraIdentityConfigÚSCOPE_AI_AZURE_DEFAULTÚhas_azure_identity_installedÚentra)Údefault_scopeÚnot_runFzyazure-identity is installed; live credential validation is skipped here. Run `hermes doctor` to verify token acquisition.z@azure-identity not installed. From the Hermes environment, run: zazure-identityz. Then restart Hermes.)Úazure_identity_installedré   Úcredential_probeÚcredential_verifiedrå  rS  rå  zazure-identity check failed: r­  ÚAZURE_FOUNDRY_API_KEY)rE  r…  r<  rÖ   r+  rö   rq  rÄ   rÜ   rÔ   Úagent.azure_identity_adapterr  r  r	  rø  Úupdateré   rÆ   r   rÊ  rÒ  rj  )Úinfor…  r<  rS  rŠ  rž  r  r  r	  Ú	installedÚ	entra_cfgÚidentity_configr¤  rø   s                 rÉ   r  r  Ÿ  sø  € ð '¨Ð8€DðßNÙ‹mˆô %/¨s´D×$9Ò$9�—‘˜Ô ¸t€IÜ�i¤×&Ò&Øˆ	Ü�I—M‘M +Ó.×;Ð;°)Ó<×BÑBÓD×JÑJÓL×YÐYÐPY€IØ!ˆÑÜ˜9Ÿ=™=¨Ó4×:Ð:¸Ó;×AÑAÓC€DˆÑà�JÔð	B÷[ñ [á4Ó6ˆIÜ.8¸¿¹ÀwÓ9OÔQU×.VÒ.V˜	 'Ö*Ð\^ˆIØ1×;Ñ;¸IÐ;ÓlˆOØ�K‰KØ)2×:OÑ:OÐbkØ$)´T¸)³_÷ ñXð WÜ#Ð$4Ó5Ð6ð 7+ð+ð ô 	-ð ˆð9Ù-Ð.EÓF×LÐLÈ"ˆô *¨'Ó2€DˆÑØ€KøôI ô Ø‹ðûô4 ô 	BØ %ˆD�ÑØ;¸C¸5ÐAˆD��MØˆûð	Bûô ô 9Ü—)’)Ð3°RÓ8Šð9úsB   †F Ã!BF- Å7G ÆG ÆF*Æ)F*Æ-GÆ8GÇGÇ"G8Ç7G8c               ó(   € V ^8„  d   QhRRRRRRRR/# ©rÂ   rø   rÄ   ÚdefaultrÀ  rÅ   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ð  s(   € ÷ 7ñ 7 sð 7°Sð 7À3ð 7È3ñ 7rË   c                ó8   € V'       d   VP                  R 4      # T# )rÛ   )rÕ   )rø   r  rÀ  s   &&&rÉ   Ú_default_api_key_base_urlr  Ð  s   € ß")ˆ7�>‰>˜#ÓÐ6¨wÐ6rË   c               ó(   € V ^8„  d   QhRRRRRRRR/# r  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   Ô  s(   € ÷ ñ  sð °Sð À3ð È3ñ rË   c                ó  € \        WV4      p ^ RIHpHp V! 4       w  rgV'       d2   V! V4      ^,          ;'       g    RP	                  4       pV'       d   TpV#   \
         d"   p	\        P                  RT	4        Rp	?	T# Rp	?	ii ; i)z²Copilot's API base comes from the token-exchange response (endpoints.api, proxy-ep fallback),
authoritative for Enterprise / proxied accounts; falls back to the registry default.r�  rÍ   z4Copilot base URL resolution fell back to default: %sN)r  r™  r‘  r’  rÜ   rÖ   r|  rl  )
rø   r  rÀ  rÃ   r‘  r’  Ú	raw_tokenrW  Úresolvedr¤  s
   &&&       rÉ   Ú_copilot_runtime_base_urlr   Ô  s€   € ô )¨¸7ÓC€HðRßXÙ,Ó.‰ˆ	ßÙ-¨iÓ8¸Õ;×AÐA¸r×HÑHÓJˆHßØ#�ð €Oøô ô RÜ�‰ÐKÈS×QÐQØ€OûðRús"   Ž.A ½A ÁA ÁBÁ%BÂBc                 ó&   € \        \        V !  4      # r*  )r    r  ©Úas   *rÉ   rÓ  rÓ  ë  s   € Ô?Ô@YÐ[\Ñ@]Ô^rË   c                 ó&   € \        \        V !  4      # r*  )rà   r  r"  s   *rÉ   rÓ  rÓ  ì  s   € Ô2Ô3LÈaÑ3PÔQrË   z)dict[str, Callable[[str, str, str], str]]Ú_API_KEY_BASE_URL_RESOLVERSc               ó    € V ^8„  d   QhRRRR/# r»  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ï  s   € ÷ +ñ +°cð +¸nñ +rË   c           	     ó  € \        V 4      pV'       d   VP                  R8w  d   \        RV  R2V RR7      h\        W4      w  r#V'       g   V R8X  d   \        pT;'       g    Rp\        V4      p\        P                  V \        4      pV! W!P                  V4      p\        V4      '       g   VP                  pV'       g+   V R8X  d$   \        V4      '       d   \        pT;'       g    R	pR
T RTRVP                  R4      RT;'       g    R/# )z5Resolve API key and base URL for an API-key provider.rø   ú
Provider 'z' is not an API-key provider.rû  ©r‡  r°  r  r  r  r¿  r‡  rÃ   rÛ   ry  )r­  rå   r¾   r«  r»   r¹  r%  rq  r  rç   rÃ  rØ   r¼   rÕ   )rn  r�  rø   r¾  rÀ  Úresolve_urlrÃ   s   &      rÉ   Ú$resolve_api_key_provider_credentialsr+  ï  s  € ä˜{Ó+€Gß�g×'Ñ'¨9Ô4ÜØ˜˜Ð%BÐCØ Ð'9ô;ð 	;ô ;¸;ÓPÑ€G÷ �{ jÔ0Ü-ˆØ×,Ð, 9ˆ
ä$ WÓ-€GÜ-×1Ñ1°+Ô?XÓY€KÙ˜7×$>Ñ$>ÀÓH€Hô ˜×"Ò"Ø×-Ñ-ˆç�{ hÔ.Ô3KÈH×3UÒ3UÜ1ˆØ×2Ð2 ?ˆ
à�K ¨G°ZÀÇÁÐQTÓAUØ�*×)Ð) 	ð+ð +rË   c               ó    € V ^8„  d   QhRRRR/# r»  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   	  s   € ÷ ñ ¸sð À~ñ rË   c                óÈ  € \        V 4      pV'       d   VP                  R8w  d   \        RV  R2V RR7      h\        V4      w  r#rEpV'       g\   VP	                  R4      '       gE   V'       d   RRP                  V4      ,           MR	p\        R
T  RT;'       g    R RV R2V RR7      hRT RVP                  ;'       g    T RVP                  R4      RT;'       g    TRVRR/# )z>Resolve runtime details for local subprocess-backed providers.r  r(  z&' is not an external-process provider.rû  r)  rö  z or set rÛ   rÍ   zCould not find the 'z' CLI command 'z(none configured)z'. Install itrÎ   Úmissing_external_process_clir‡  rø   rÃ   rð  rò  ry  Úprocess)r­  rå   r¾   ró  rY  r~  rã   rÕ   )rn  r�  rð  rò  rÃ   rÄ  rî  Ú_hints   &       rÉ   Ú-resolve_external_process_provider_credentialsr1  	  s  € ä˜{Ó+€Gß�g×'Ñ'Ð+=Ô=ÜØ˜˜Ð%KÐLØ Ð'9ô;ð 	;ô CYÐY`ÓBaÑ?€G�8Ð/?ß H×$7Ñ$7¸×$EÒ$Eß;K�
˜SŸX™XÐ&6Ó7Ö7ÐQSˆÜØ" ; -ð 0Ø×.Ð.Ð.Ð/¨}¸U¸GÀ1ðFà Ø/ô	1ð 	1ð 	�K ¨G¯J©J×,EÐ,E¸+Ø�H—O‘O CÓ(¨)Ð5E×5PÐ5PÈÐRXÐZ^Ø�)ðð rË   Úclear_defaultc          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
rÂ   rn  rÄ   rç   Údefault_modelrz  r2  rÆ   rÅ   r   rÇ   )rÈ   s   "rÉ   rÊ   rÊ   (	  s4   € ÷ -ñ -Øð-Ø*-ð-Ø>Kð-àð-à'+ñ-rË   c               ó  € \        4       ;_uu_ 4        \        4       pWR&   \        V4       RRR4       \        4       pVP                  P                  RRR7       \        V4       \        4       pVP                  R4      p\        V\        4      '       d   \        V4      pM%\        V4      '       d   RVP                  4       /M/ pWR&   V'       d,   VP                  4       '       d   VP                  R4      VR	&   MVP                  R	R4       ^ R
IHp	 V	! V4       V'       d'   VP                  RR4      p
V
'       d   RV
9   d   W(R&   MV'       d   VP                  RR4       W†R&   \#        WV4       V#   + '       g   i     ELU; i)aö  Update config.yaml and auth.json to reflect the active provider.

*default_model*, when given, is written as ``model.default`` in the same step so the gateway
(which re-reads config per message) can't pick up the new provider before model selection
finishes and send an OpenRouter-style ``vendor/model`` name to a direct API. *clear_default*
removes ``model.default`` in that same write, for a caller that has no model to offer and must
not leave the previous provider's model paired with the new host.rg  NTrA  r†  r  r‡  rÛ   rÃ   )Ú clear_model_endpoint_credentialsrÍ   )rZ  rã  r  r2  rE  rF  r4  r3  rq  r+  rö   rÃ  rÜ   rÕ   rá  rE  r6  r0  )rn  rç   r4  r2  rz  Úconfig_pathÚconfigÚcurrent_modelrŠ  r6  Úcur_defaults   &&&$       rÉ   Ú_update_config_for_providerr;  (	  sI  € ô 
×	Õ	Ü%Ó'ˆ
Ø(3Ð$Ñ%Ü˜Ô$÷ 
ô
 "Ó#€KØ×Ñ×Ñ T°DÐÔ9Ü(¨Ô5ÜÓ€FØ—J‘J˜wÓ'€MÜ�-¤×&Ò&Ü˜Ó'‰	ä:GÈ×:VÒ:V�Y × 3Ñ 3Ó 5Ñ6Ð\^ˆ	Ø'ˆjÑßÐ0×6Ñ6×8Ò8Ø 2× 9Ñ 9¸#Ó >ˆ	�*Òà�‰�j $Ô'õ CÙ$ YÔ/÷ Ø—m‘m I¨rÓ2ˆß˜c [Ô0Ø#0�iÑ øß	Ø�‰�i Ô&Øˆ7�OÜ˜+Ô.ØÐ÷G 
×	Ð	ús   “E9Å9F
	c               ó   € V ^8„  d   QhRR/# r0  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   X	  s   € ÷ Uñ U˜mñ UrË   c                 óD  €  \        4       p T '       d   T P                  R4      MRp\        T\        4      '       d   TP                  R4      MRp\        T\
        4      '       d)   TP                  4       P                  4       ;'       g    R# R#   \         d     R# i ; i)z?Return model.provider from config.yaml, normalized, if present.Nr†  r‡  )r3  rÖ   rq  r+  rö   rÄ   rÜ   rÔ   )r8  r†  r‡  s      rÉ   Ú_get_config_providerr>  X	  sƒ   € ðÜ Ó"ˆ÷ $*ˆF�J‰J�wÔ¨t€EÜ(2°5¼$×(?Ò(?ˆu�y‰y˜Ô$ÀT€HÜ1;¸HÄc×1JÒ1JˆH�N‰NÓ×"Ñ"Ó$×,Ð,¨ÐTÐPTÐTøô	 ô Úðús   ‚
B ÂBÂBc               ó    € V ^8„  d   QhRRRR/# r}  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   c	  s   € ÷ Tñ T¸ð TÈ4ñ TrË   c                óŽ   € T ;'       g    RP                  4       P                  4       pV\        9   ;'       d    \        4       V8H  # )zWTrue when logout should reset model.provider (a registry provider config.yaml selects).rÍ   )rÜ   rÔ   r/  r>  r®  s   & rÉ   Ú'_should_reset_config_provider_on_logoutrA  c	  s>   € à×#Ð# ×*Ñ*Ó,×2Ñ2Ó4€JØÔ*Ñ*×SÐSÔ/CÓ/EÈÑ/SÐSrË   c               ó   € V ^8„  d   QhRR/# r0  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   i	  s   € ÷ Bñ B¨mñ BrË   c                 ó�   € \        4       p \        P                  T ;'       g    R4      pV'       d   VP                  '       d   V # R# )uß   Fallback logout target when auth.json has no active provider but config.yaml still selects an
OAuth provider (e.g. openai-codex) â€” otherwise logout said "No provider is currently logged in"
and never reset model.provider.rÍ   N)r>  r—  rq  r€  )r‡  Úflows     rÉ   Ú$_logout_default_provider_from_configrE  i	  s:   € ô $Ó%€HÜ×#Ñ# H§N N°Ó3€Dß × 7× 7Ð 7ˆ8ÐA¸TÐArË   c               ó   € V ^8„  d   QhRR/# rÅ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   r	  s   € ÷ ñ  ñ rË   c                 ó  € \        4       p V P                  4       '       g   V # \        V 4       \        4       pV'       g   V # VP	                  R4      p\        V\        4      '       d   RVR&   RV9   d
   \        VR&   \        W4       V # )z5Reset config.yaml provider back to auto after logout.r†  r¹  r‡  rÃ   )	r2  rÝ  r4  r3  rq  r+  rö   r   r0  )r7  r8  r†  s      rÉ   Ú_reset_config_providerrH  r	  s}   € ä!Ó#€KØ×Ñ×ÒØÐÜ(¨Ô5ÜÓ€FßØÐØ�J‰J�wÓ€EÜ�%œ×ÒØ"ˆˆjÑØ˜ÔÜ 3ˆE�*ÑÜ˜+Ô.ØÐrË   c               ó   € V ^8„  d   QhRR/# r‚  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   „	  s   € ÷ ñ ˜4ñ rË   c                ó.   € \        R4       \        ^ 4      h)z9Deprecated: use 'hermes model' or 'hermes setup' instead.zœThe 'hermes login' command has been removed.
Use 'hermes auth' to manage credentials,
'hermes model' to select a provider, or 'hermes setup' for full setup.)ÚprintÚ
SystemExit)rò  s   &rÉ   Úlogin_commandrM  „	  s   € ä	ð Sô Tä
�Q‹-ÐrË   c               ó   € V ^8„  d   QhRR/# rØ  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ‹	  s   € ÷ Xñ X ~ñ XrË   c            
     óp  € \        R4      p V '       d   V P                  R4      '       g   RRRR/#  \        P                  ! V P                  RR4      4      P	                  4       \
        P
                  ! 4       8„  pRVRRR	V P                  R	R
4      RV P                  R4      /#   \         d    Rp L8i ; i)z3Return auth status dict for MiniMax OAuth provider.r  r—  rå  Fr‡  r\  rÍ   Tr  r  )r+  rq  r	   r  r  rL  rÖ   )rˆ  Útoken_valids     rÉ   r–  r–  ‹	  s®   € ä# OÓ4€Eß˜Ÿ	™	 .×1Ò1Ø˜U J°Ð@Ð@ðÜ×,Ò,¨U¯Y©Y°|ÀRÓ-HÓI×SÑSÓUÔX\×XaÒXaÓXcÑcˆð 	�[ *¨oØ�%—)‘)˜H hÓ/°¸u¿y¹yÈÓ?VðXð Xøô ô ØŠðús   ²A
B% Â%B5Â4B5c               ó   € V ^8„  d   QhRR/# r‚  rÇ   )rÈ   s   "rÉ   rÊ   rÊ   ™	  s   € ÷ !Kñ !K˜Dñ !KrË   c                óÞ  € \        V RR4      pV'       d+   \        V4      '       g   \        RV 24       \        ^4      hT;'       g    \	        4       ;'       g    \        4       pV'       g   \        R4       R# VR8X  d-   ^ RIHpHp V! \        R4      4      '       d   \        V4       R# \        V4      p\        V4      p\        V4      '       g   V'       g   \        RV R24       R# VR8X  d   ^ R	IHp V! R
4       V'       d   \        4        \        RV R24       V'       g   \        R4       R# \         P"                  ! R4      '       d   \        R4       R# \        R4       R# )z Clear auth state for a provider.r‡  NzUnknown provider: z#No provider is currently logged in.rü   )ÚFREE_TIER_NOT_SIGNED_INrT  zNo auth state found for rÎ   )Ú_clear_shared_nous_stateÚlogoutzLogged out of z+Model provider configuration was unchanged.rÛ  z)Hermes will use OpenRouter for inference.z9Run `hermes model` or configure an API key to use Hermes.)r   r°  rK  rL  r2  rE  ræ  rS  rT  r+  rA  r´  r€  Úhermes_cli.auth_nousrT  rH  rÊ  rÒ  )rò  rn  rr  rS  rT  Úshould_reset_configr†  rT  s   &       rÉ   Úlogout_commandrX  ™	  s  € ä˜$ 
¨DÓ1€KßÔ1°+×>Ò>ÜÐ" ; -Ð0Ô1Ü˜‹mÐØ×[Ð[Ô/Ó1×[Ð[Ô5YÓ5[€FßÜÐ3Ô4ÙØ�ÔßPÙÔ1°&Ó9×:Ò:äÐ)Ô*ÙÜAÀ&ÓIÐÜ2°6Ó:€MÜ ×'Ò'×+>ÜÐ(¨¨°qÐ9Ô:ÙØ�ÔåAÙ  Ô*ßÜÔ Ü	ˆN˜=˜/¨Ð
+Ô,ßÜÐ;Ö<Ü	�ŠÐ'×	(Ò	(ÜÐ9Ö:äÐIÖJrË   )rÍ   rø   )z
openai-apiz
OpenAI APIzhttps://api.openai.com/v1)rÜ  ÚOPENAI_BASE_URL)r  z	LM Studiozhttp://127.0.0.1:1234/v1)Ú
LM_API_KEYÚLM_BASE_URL)ÚCOPILOT_GITHUB_TOKENÚGH_TOKENÚGITHUB_TOKEN)r  zGoogle AI Studioz0https://generativelanguage.googleapis.com/v1beta)ÚGOOGLE_API_KEYÚGEMINI_API_KEYÚGEMINI_BASE_URL)r  z
Z.AI / GLMzhttps://api.z.ai/api/paas/v4)ÚGLM_API_KEYÚZAI_API_KEYÚZ_AI_API_KEYÚGLM_BASE_URL)r	  zKimi / Moonshotzhttps://api.moonshot.ai/v1)ÚKIMI_API_KEYÚKIMI_CODING_API_KEYÚKIMI_BASE_URL)r
  zKimi / Moonshot (China)zhttps://api.moonshot.cn/v1)ÚKIMI_CN_API_KEY)ÚSTEPFUN_API_KEY)r  zArcee AIzhttps://api.arcee.ai/api/v1)ÚARCEEAI_API_KEYÚARCEE_BASE_URL)r  z	GMI Cloudzhttps://api.gmi-serving.com/v1)ÚGMI_API_KEYÚGMI_BASE_URL)ÚACTUAL_API_KEY)ÚminimaxÚMiniMaxz https://api.minimax.io/anthropic)ÚMINIMAX_API_KEYÚMINIMAX_BASE_URL)r  Ú	Anthropiczhttps://api.anthropic.com)ÚANTHROPIC_API_KEYÚANTHROPIC_TOKENr  ÚANTHROPIC_BASE_URL)Úalibabaz
Qwen Cloudz6https://dashscope-intl.aliyuncs.com/compatible-mode/v1)ÚDASHSCOPE_API_KEYÚDASHSCOPE_BASE_URL)r  zAlibaba Cloud (Coding Plan)z-https://coding-intl.dashscope.aliyuncs.com/v1)ÚALIBABA_CODING_PLAN_API_KEYry  ÚALIBABA_CODING_PLAN_BASE_URL)r  zMiniMax (China)z"https://api.minimaxi.com/anthropic)ÚMINIMAX_CN_API_KEYÚMINIMAX_CN_BASE_URL)ÚdeepseekÚDeepSeekzhttps://api.deepseek.com/v1)ÚDEEPSEEK_API_KEYÚDEEPSEEK_BASE_URL)r  ÚxAIzhttps://api.x.ai/v1)ÚXAI_API_KEYÚXAI_BASE_URL)Únvidiaz
NVIDIA NIMz#https://integrate.api.nvidia.com/v1)ÚNVIDIA_API_KEYÚNVIDIA_BASE_URL)r  zVercel AI Gatewayzhttps://ai-gateway.vercel.sh/v1)ÚAI_GATEWAY_API_KEYÚAI_GATEWAY_BASE_URL)r  zOpenCode Zenzhttps://opencode.ai/zen/v1)ÚOPENCODE_ZEN_API_KEYÚOPENCODE_ZEN_BASE_URL)r  zOpenCode Gozhttps://opencode.ai/zen/go/v1)ÚOPENCODE_GO_API_KEYÚOPENCODE_GO_BASE_URL)r  z	Kilo Codezhttps://api.kilo.ai/api/gateway)ÚKILOCODE_API_KEYÚKILOCODE_BASE_URL)r   zHugging Facez https://router.huggingface.co/v1)ÚHF_TOKENÚHF_BASE_URL)r!  zXiaomi MiMozhttps://api.xiaomimimo.com/v1)ÚXIAOMI_API_KEYÚXIAOMI_BASE_URL)r"  zTencent TokenHubz#https://tokenhub.tencentmaas.com/v1)ÚTOKENHUB_API_KEYÚTOKENHUB_BASE_URL)r#  zTencent TokenPlanz2https://api.lkeap.cloud.tencent.com/plan/anthropic)ÚTOKENPLAN_API_KEYÚTOKENPLAN_BASE_URL)ÚOLLAMA_API_KEY)r%  zAWS Bedrockz/https://bedrock-runtime.us-east-1.amazonaws.comrÇ   ÚBEDROCK_BASE_URLr&  )ÚvertexzGoogle Vertex AIrÍ   rÇ   rÍ   r›  )r'  zAzure FoundryrÍ   )r  ÚAZURE_FOUNDRY_BASE_URL>   Ú*ÚnoneÚnullÚdummyÚexampleÚchangemeÚplaceholderÚyour_api_keyÚyour_api_key_hereú**ú***úyour-api-key)zsk-Úghp_Úhf_)zsk-or->   Úaccount_missingÚno_usable_creditsÚsubscription_expiredÚmember_spend_cap_exceededr*  )rä  rõ  Úlast_error_codeÚlast_error_reasonÚlast_error_messageÚlast_error_reset_atrö  )r—  rÍ  r\  Úexpires_at_msr/  Úobtained_atr�  Ú	agent_keyÚagent_key_expires_atÚagent_key_expires_inÚagent_key_idÚagent_key_obtained_atÚagent_key_reusedré   rç   >   ÚmanualÚdevice_codeÚhermes_pkceÚloopback_pkce)r›  zgoogle-vertexz	vertex-aiz
gcp-vertexÚvertexai)r—  rÍ  r\  r/  r´  >   rÏ   rÒ   úportal.nousresearch.com>   Úinvalid_grantÚinvalid_tokenÚrefresh_token_reused>   rM  r[  r]  (˜  Ú__conditional_annotations__rô   Ú
__future__r   Úpmr   r  rh  ÚloggingrÊ  rj  rê  rÿ  rL  Ú
webbrowserÚ
contextlibr   r   Údataclassesr   r   Ú	functoolsr   r	   r
   r   Úpathlibr   Útypingr   r   r   r   r   r   r   r   Úurllib.parser   r¼  r   r   r   Úagent.credential_persistencer   Úutilsr   r   r   r   Úhermes_cli.auth_zai_kimir   r   r    r!   r"   r#   Úhermes_cli.auth_model_pickerr$   r%   Úhermes_cli.auth_device_flowr&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   Úhermes_cli.auth_oauth_grantsr4   r5   r6   r7   r8   r9   rV  r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   ra   Úhermes_cli.auth_minimaxrb   rc   rd   re   rf   rg   rh   ri   rj   rk   rl   rm   rn   Úhermes_cli.auth_xairo   rp   rq   rr   rs   rt   ru   rv   rw   rx   ry   rz   r{   r|   r¯  r}   r~   r   r€   r�   r‚   rƒ   r„   r…   r†   r‡   rˆ   r‰   rŠ   r‹   rŒ   r�   Úhermes_cli.auth_openrouterrŽ   Úhermes_cli.guest_handoffr�   Úhermes_cli.auth_qwenr�   r‘   r’   r“   r”   r•   r–   Úhermes_cli.auth_constantsr—   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À   Ú	getLoggerrð   r|  r  rÖ   r  rØ   rà   râ   rû   r(  rõ   rã   r/  r�  ÚBUILTIN_PROVIDER_IDSrE  r0  r1  r2  r3  r4  Ú hermes_cli.auth_plugin_providersr5  r6  r­  r7  rH  rh  r[  rc  rj  rl  rr  rw  r€  r‹  r«  r²  rµ  r¾  r½  rÀ  rÃ  rÐ  rÖ  ré  rê  ÚLockrý  rÌ  rõ  rø  r  r  ÚEACCESÚEAGAINr   r  r  r,  r5  r9  rT  rZ  r_  rã  rx  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.  r2  r7  r;  rV  r\  rd  rn  rr  r_  rj  rZ  ru  rv  r{  r€  r„  r”  rœ  rÃ  rË  r×  rß  ré  rð  rô  rõ  r»  r  r  r  r  r%  r+  r-  r1  r4  r6  rI  r7  rb  rC  r@  ru  ri  rÞ  rm  rp  ry  r|  Ú_OAUTH_GRANT_DEAD_CODESÚ_NOUS_AUTH_MISSING_CODESr—  rš  Ú_is_terminal_nous_refresh_errorÚ$_is_terminal_xai_oauth_refresh_errorÚ&_is_terminal_codex_oauth_refresh_errorr¦  r�  r“  r¹  rÂ  rÉ  rÈ  ró  rú  rý  rç  rÀ  r~  r   r  r  r  r   r%  r+  r1  r;  r>  rA  rE  rH  rM  r–  rX  )rQ  r+  rD  rÄ  s   000@rÉ   Ú<module>ræ     sE  øðô	Xõ #å Û Û Û Û 	Û Û Û Û Û ç 0ß (Ý ß ,Ñ ,Ý ß R× RÓ RÝ !ç TÑ TÝ Mß OÓ O÷0÷ 0÷1÷(÷ (÷ (÷ (÷*÷ *÷B÷ B÷ B÷ B÷ B÷ B÷ B÷ B÷ B÷ Bó B÷/÷ /÷ /õ /÷e÷ e÷ e÷ e÷A÷ A÷ A÷ Aõ Aõ >Ý 5÷&÷ &ñ &÷[÷ [÷ [÷ [÷ [÷ [÷ [÷ [÷ [÷ [÷ [ð  
×	Ó	˜8Ó	$€ðÛðÛõ@õð& ÷ð ó ð÷Nð NðJ#bÙØ�Ð2ÐD[Ø5ÐAWØ ô"ðJ#bñ
 �> >Ð3CÐXnÔoðJ#bñ fðJ#bñ ØÐ<Ð>NØ5ô7ðJ#bñ �< Ð/?ÐTiÔjðJ#bñ ZðJ#bð Ð Ð"@Ù9Ð;QðSðJ#bñ ØÐ+Ð-?Ø7ÐJ`ôbðJ#bñ">ð#J#bñ&Eð'J#bñ.?ð/J#bñ2 fð3J#bð4 Ð#Ð%DÑFZÐ\nÐoð5J#bñ6 að7J#bñ8 ]ð9J#bð: Ð Ð"9Ñ;NÐPaÐbð;J#bñ< ið=J#bñ> ØÐ<¸oØ1ÐFdØ)Ð1DØ˜Ð#7Ð9NØ&Ð(BðDô	Eð?J#bñT`ðUJ#bñX3ðYJ#bñ\[ð]J#bñ`ðaJ#bñd hðeJ#bñf LðgJ#bñh lðiJ#bñjðkJ#bñnðoJ#bñvðwJ#bñz mð{J#bñ| fð}J#bñ~ gðJ#bñ@ðAJ#bñD3ðEJ#bðH �^Ð%BÑDWÐYjÐkðIJ#bñJðKJ#bñR 9ðSJ#bñT añUJ#b€�ó JbñX mÑ]kÔló0Ùl�‡D‚Dˆ!‚GÑlñ0Ð Ð,ó ñ !Ð!2Ó3Ð ÷tõ t÷
fñ fñ Ô õ
dó7Ð ñ 3Ð õ>ð4°q÷ 4ð 4ð ‘+ð1Ñ Ð-ó ö
LöGöö$Wö&;ö@7ö0ð ÐvØÐcð!eÑ ñ %Ñ%BÓCó Gaõ aÑ öö*:ö
ö	]öðD 9;Ñ Ð5Ó :Ø"+§.£.Ó"2Ñ ööö öcö_ñ $ñ $hØ—l’l E§L¢L²'¸%ÀÈDÓ2QÑRó$hó hÑ ö0öIö.öð ô9ó ñ9ðx à6ñØY]÷ó ñö<÷-ñ -ð`TÀU÷ Tð T÷ñ öö<öböHð à3Löjó ñjð"4Ðuy÷ 4ð 4öKö
,ðEØV[÷Eð Eö\ö)ö4ö
ö÷Lñ Lñ60Ñ ñ!Ñ ö=ö]ð#Gð
 ,0ð#Gð !÷#Gð #GöL/ödTð)à+/ð)ð 37ð)ð 9=÷	)ð )öX	ö
%ööö&Aö
6ö$5ö
1ö
aöVö<]ñ Ð 9Ð:Ó;Ñ Ù"Ó#\Ó]Ñ ÙYÑ öFö ö(_öñ* ˜$ÐÑ":¸DÐ!AÙ&¨Ð.Ñ1MÈtÐ0TÙ*¨DÐ1ðK3Ñ ÑGô 3÷ð ÷"ó ÷,%ð %÷ð ÷,ð ð2%%2Ù	ˆ5ð%%2Ù˜%ð%%2Ù!'¨ð%%2Ù07¸ð%%2áˆhð%%2á'¨ð%%2á3EÀxð%%2ñ ˆEð%%2ñ ˜5ð%%2ñ #)¨%ð%%2ð �ð	%%2ñ +¨Kð	%%2ñ
 �+ð%%2ñ
  0°ð%%2ñ ˆMð%%2ñ -¨mð%%2ñ >HÈñ%%2ñ Ðð%%2ñ "/Ð0@ð%%2ñ ˆIð%%2ñ -¨ið%%2ñ �ð%%2ñ # Gð%%2ñ �ð%%2ñ # Eð%%2ñ �xð%%2ñ "2°8ð%%2ñ >CÀHð%%2ñ �\ð%%2ñ $0°ð%%2ñ �oð%%2ñ (8¸ð%%2ñ KZÐ[jð%%2ñ Ð+ò%%2ñ .>Ð?Tð%%2ñ Ð0ð%%2ñ  ˆkð!%%2ñ  )¨+ð!%%2ñ" ˆið#%%2ñ" *¨9ð#%%2ñ$ �Yð%%%2ñ$ !/°	ð%%%2ñ& ˜-ð'%%2ñ& *=¸mð'%%2ñ( �ð)%%2ñ(  (¨ð)%%2ñ( 8KÈLð)%%2ñ* �ð+%%2ñ* !& ~ð+%%2ñ, �<ð-%%2ñ, ",¨\ò-%%2ð, <HÈð-%%2ñ. 	ˆ-ð/%%2ñ. (¨ð/%%2ñ. 9JÈ=ð/%%2ñ0 ˆHð1%%2ñ0 $ Xð1%%2ñ2 Ð!ð3%%2ñ2 $.Ð/Að3%%2ñ4 Ð'ð5%%2ñ4 *7Ð8Jð5%%2ñ6 Ð$ð7%%2ñ6 '6Ð7Jð7%%2ñ8 
ˆ9ð9%%2ñ8 $ Yð9%%2ñ8 1AÀ)ð9%%2ñ8 NVÐW`ð9%%2ñ: 	ˆ-ò;%%2ñ: +¨Mð;%%2ñ< ˆJð=%%2ñ< $ Zð=%%2ñ< 2@Àð=%%2ð> �
ð?%%2ñ> (¨ð?%%2ñ> 6AÀ*ð?%%2ñ@ ˆ~ðA%%2ñ@  /°ðA%%2ñD ‰XðE%%2ñF ‰hðG%%2ñF '¨ðG%%2ñH ‰HðI%%2ñH !¡(ðI%%2ñJ ‘ðK%%2ñJ '©ñK%%2Ñ ‘>ô %2÷P
ð 
÷2ð 2÷*ð ñ0¸u÷ ò ÷'ð 'ñ\ & y°*Ð&=Ó>Ñ ÷ð ó.['ð '+ñ['ð (,ñ	['ð
 !÷['ó ['÷@@ð @÷
ð ÷Rð R÷
cð cñ
-ØSW÷-ò -ñ fÑ ÷Xð X÷ð ÷ð ñ .7ó 89ó .:Ñ ™Nô :ð &ŸN›NÓ,Ñ Ø57Ñ Ñ2Ô 7Ù Ñ ñ4á!ñ4ð  $ñ4ð  $ñ	4ð
 !B÷4ò 4÷M0ð M0ñl #Ñ ØX\Ñ ÑUÔ \ð GKÑ ÑCÔ J÷.ð .÷#ð #÷ð ñ" �$Õ÷Xò Xó ñXñ2 $Ó$^Ó_Ñ ñ %ó &^ó _Ñ ð ÒØÑ2Ñ4JÙ6Ñ9QÕQÐfjõlð Ò%ØÑ;Ñ=TÙ6Ñ:PÑRtÐ9uÕuØõ!ð Ò"ØÑ<Ñ>YÙ(Ñ*>Ñ@`Ð)aÓbØõ!ð Ò#ØÑ8Ñ:PóRàÒ&ØÑDÑFeógð6Ñ Ñ2ô ÷&Ið Iñ
 #*Ñ*DÈvÕ"VÑ Ù'.Ñ/IÐT_Õ'`Ñ $Ù)0Ù¨õ*9Ñ &÷0ð 0÷ð ÷Zð Z÷	_ð 	_÷7ð 7÷,
Yð 
Y÷!ð !÷H`ð `÷,\ð \÷"Xð X÷ ó  ð&-7Ù,@×,FÒ,FÔ,HÔIÑ,H™y˜s€s�NŠNÒÑ,HÒIð-7àÑ5ñ-7Ñ ™>ô 7ð Ñ>ØÑ,ØÑ)àÑ7ØÑ4ð(6Ñ ‘nô 6÷.ð .÷b7ð 7÷ð ð& Ð)ØÐ,Ø	Ð ØÑ(ØÒ^ØÒQðJSÑ ÑFô S÷+ð +÷>ð ó4-à"÷-ó -÷`Uð U÷Tð T÷Bð B÷ð ÷$ð ÷Xð X÷!Kò !KøðWI ô ØƒEðûð ô ØƒFðüòJ0ùóz< Js0   Èl, È"l< Ì$mémì,	l9ì8l9ì<	m	ím	