+
    iHàjOE  ã                  ó`  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Ht ^ RIHtHtHtHt ]P$                  ! ]4      tRtRtRtR	]! R4       2tRBtR
 R ltR tR R lt]! RR7       ! R R4      4       t]P<                  ! ^R7      R R l4       t/ t R]!R&   Rt"R R lt#R R lt$R R lt%R R  lt&RCR!RR"R/R# R$ lllt'R% R& lt(RCR!RR'R(R)R/R* R+ lllt)R, R- lt*R. R/ lt+R0R1 3R2R3 3R4R5 33t,RCR6RR'R(R)R/R7 R8 lllt-R9 R: lt.R; R< lt/R= R> lt0R?R/R@ RA llt1. RDOt2R# )Euø  Microsoft Entra ID adapter for Microsoft Foundry.

Keyless auth via the `azure-identity` ``DefaultAzureCredential`` chain (env service principal â†’
workload identity â†’ managed identity â†’ VS Code â†’ Azure CLI â†’ azd â†’ PowerShell â†’ broker). Mirrors
``agent/bedrock_adapter.py``: `azure-identity` is imported lazily (only for ``auth_mode = entra_id``);
``build_token_provider`` returns the zero-arg callable the OpenAI SDK calls before every request
(transparent refresh); consumer helpers are split by purpose so logging paths never mint tokens and
tokens never leak into cache keys; no JWT is persisted (azure-identity caches in-process / OS keychain).
Reference: https://learn.microsoft.com/azure/ai-foundry/foundry-models/how-to/configure-entra-id
)Úannotations)Úinstall_hintN)Ú	dataclass)ÚAnyÚCallableÚDictÚOptionalzhttps://ai.azure.com/.defaultzazure-identityzWThe 'azure-identity' package is required for Azure AI Foundry Entra ID authentication. zRun: c               ó   € V ^8„  d   QhRR/# )é   ÚreturnÚbool© )Úformats   "ÚA/home/ubuntu/.hermes/hermes-agent/agent/azure_identity_adapter.pyÚ__annotate__r   )   s   € ÷ ñ  dñ ó    c                 ó4   €  ^ RI p R#   \         d     R# i ; i)uA   Cheap importability check â€” does not walk the credential chain.NTF)Úazure.identityÚ	Exception)Úazures    r   Úhas_azure_identity_installedr   )   s   € ðÛÙøÜô Úðús   ‚ ˆ–c                 ó(  €  ^ RI Hp  V #   \         d}     ^ RIHpHp M*  \         d   p\        \        R,           4      ThRp?ii ; i T! \        4       M/  T d&   p\        \        \        T4      ,           4      ThRp?ii ; i^ RI Hp  T u # i ; i)zhImport ``azure.identity``, lazy-installing if allowed; ImportError with an actionable message otherwise.N)ÚInstallErrorÚensure_importzRun: hermes pm repair)	r   ÚidentityÚImportErrorÚpmr   r   Ú_INSTALL_MSGÚ_AZURE_IDENTITY_FEATUREÚstr)Ú_air   r   Úexcs       r   Ú_require_azure_identityr"   2   sŽ   € ðÝ$Øˆ
øÜô 
ð	Oß6Ð6øÜô 	OÜœlÐ-DÕDÓEÈ3ÐNûð	Oúð	@ÙÔ1Õ2øØô 	@Üœl¬S°«XÕ5Ó6¸CÐ?ûð	@úå$ØŠ
ð
úsR   ‚
 ŠB–žBŸAªAÁAÁBÁ
AÁBÁBÁ A>Á>BÂBÂBc               ó   € V ^8„  d   QhRR/# ©r
   r   ÚNoner   )r   s   "r   r   r   D   s   € ÷ !ñ ! ñ !r   c                 ó€   € \        \        RR4      p \        V 4      '       d   V ! 4        \        P	                  4        R# )zaClear the cached credentials (tests, profile switches); tolerates a monkeypatched plain function.Úcache_clearN)ÚgetattrÚ_default_chain_credentialÚcallableÚ_credentials_by_homeÚclear)r'   s    r   Úreset_credential_cacher-   D   s-   € äÔ3°]ÀDÓI€KÜ�×ÒÙŒÜ×ÑÖ r   T)Úfrozenc                  ón   € ] tR t^Lt$ Rt]tR]R&   RtR]R&   R R lt	R	 R
 lt
]RR/R R ll4       tRtR# )ÚEntraIdentityConfiga=  Hermes-managed Entra knobs; everything else (tenant, SP secret, federated token file, authority...) flows
through azure-identity's standard ``AZURE_*`` env vars. ``exclude_interactive_browser`` keeps probes
non-interactive (the setup wizard never writes it). Frozen: hashable for ``lru_cache``, picklable for workers.r   ÚscopeTr   Úexclude_interactive_browserc               ó   € V ^8„  d   QhRR/# r$   r   )r   s   "r   r   Ú EntraIdentityConfig.__annotate__U   s   € ÷ cñ c˜tñ cr   c                	ó¦   € \         P                  T R \        V P                  ;'       g    R4      P	                  4       ;'       g    \
        4       R# )r1   Ú N)ÚobjectÚ__setattr__r   r1   ÚstripÚSCOPE_AI_AZURE_DEFAULT©Úselfs   &r   Ú__post_init__Ú!EntraIdentityConfig.__post_init__U   s7   € Ü×Ñ˜4 ¬#¨d¯j©j×.>Ð.>¸BÓ*?×*EÑ*EÓ*G×*aÐ*aÔKaÖbr   c               ó   € V ^8„  d   QhRR/# )r
   r   údict[str, Any]r   )r   s   "r   r   r4   X   s   € ÷ fñ f˜ñ fr   c                	ó6   € R V P                   RV P                  /# ©r1   r2   rB   r;   s   &r   Úto_dictÚEntraIdentityConfig.to_dictX   s   € Ø˜Ÿ™Ð%BÀD×DdÑDdÐeÐer   Údefault_scopeNc               ó$   € V ^8„  d   QhRRRRRR/# )r
   ÚdataúOptional[dict[str, Any]]rE   úOptional[str]r   r0   r   )r   s   "r   r   r4   \   s#   € ÷ 
ñ 
Ð5ð 
Èð 
Ðbuñ 
r   c          	     	óð   € T;'       g    / pT ! \        VP                  R 4      ;'       g    R4      P                  4       ;'       g    T;'       g    \        \	        VP                  RR4      4      R7      # )r1   r6   r2   TrB   )r   Úgetr9   r:   r   )ÚclsrG   rE   s   &&$r   Ú	from_dictÚEntraIdentityConfig.from_dict[   sb   € à�zˆz�rˆÙÜ�d—h‘h˜wÓ'×-Ð-¨2Ó.×4Ñ4Ó6×aÐa¸-×aÐaÔKaÜ(,¨T¯X©XÐ6SÐUYÓ-ZÓ([ô
ð 	
r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r:   r1   Ú__annotations__r2   r=   rC   ÚclassmethodrM   Ú__static_attributes__r   r   r   r0   r0   L   sG   ‡ ñvð (€Eˆ3Ó'Ø(,Ð Ó,õcõfð ð
ÐY]ö 
ó ô
r   r0   )Úmaxsizec               ó    € V ^8„  d   QhRRRR/# ©r
   Úconfigr0   r   r   r   )r   s   "r   r   r   e   s   € ÷ /ñ /Ð&9ð /¸cñ /r   c                ój   € \        4       pV P                  '       d   / MRR/pVP                  ! R/ VB # )záCached ``DefaultAzureCredential`` for the unscoped process. ``maxsize=1`` is intentional: a process uses
one ``model.entra.*`` block at a time. Only Hermes knobs are passed as kwargs; the rest comes from ``AZURE_*``
env vars.Ú&exclude_interactive_browser_credentialFr   )r"   r2   ÚDefaultAzureCredential)rZ   ÚaiÚkwargss   &  r   r)   r)   d   s9   € ô
 
!Ó	"€Bà×5×5Ð5‰RÐ<dÐfkÐ;l€FØ×$Ò$Ñ. vÑ.Ð.r   zdict[tuple, Any]r+   aæ  Entra ID auth is refused for this profile: it sets no AZURE_* credential of its own, and under multiplexed profiles the ambient DefaultAzureCredential chain (process env, az CLI caches, host managed identity) mints the LAUNCH profile's identity, which would be sent to this profile's base_url. Set AZURE_TENANT_ID + AZURE_CLIENT_ID + AZURE_CLIENT_SECRET or AZURE_FEDERATED_TOKEN_FILE in this profile's own config; AZURE_CLIENT_ID alone selects the host's user-assigned managed identity.c               ó$   € V ^8„  d   QhRRRRRR/# )r
   r^   r   rZ   r0   r   r   )r   s   "r   r   r   �   s"   € ÷ /ñ /˜3ð /Ð(;ð /Àñ /r   c                óB  a€ ^ RI HpHp V! 4       ;'       g    / oV3R lpV! R4      V! R4      reV'       d/   V'       d'   V! R4      '       d   V P                  WVV! R4      4      # V'       d0   V'       d(   V! R4      '       d   V P	                  WVV! R4      R7      # V'       d7   V'       g/   V! R4      '       g!   V! R4      '       g   V P                  VR7      # V! 4       '       d   \        \        4      hVP                  '       d   / MR	R
/pV P                  ! R/ VB # )é    )Úcurrent_secret_scopeÚis_multiplex_activec                óV   <€ SP                  V 4      ;'       g    R P                  4       # ©r6   )rK   r9   )Únamer1   s   &€r   Ú<lambda>Ú$_scoped_credential.<locals>.<lambda>„   s   ø€ ˜Ÿ™ 4›×.Ð.¨B×5Ñ5Ô7r   ÚAZURE_TENANT_IDÚAZURE_CLIENT_IDÚAZURE_CLIENT_SECRETÚAZURE_FEDERATED_TOKEN_FILE)Ú	tenant_idÚ	client_idÚtoken_file_path)ro   r\   Fr   )
Úagent.secret_scoperc   rd   ÚClientSecretCredentialÚWorkloadIdentityCredentialÚManagedIdentityCredentialÚRuntimeErrorÚ_AMBIENT_CHAIN_REFUSALr2   r]   )	r^   rZ   rc   rd   ÚreadÚtenantÚclientr_   r1   s	   &&      @r   Ú_scoped_credentialrz   �   s  ø€ ßLÙ Ó"×(Ð( b€EÜ7€DÙÐ+Ó,©dÐ3DÓ.EˆFß—&™TÐ"7×8Ò8Ø×(Ñ(¨¹Ð>SÓ9TÓUÐUß—&™TÐ">×?Ò?Ø×,Ñ,°vÑaeð  gCó  bDÐ,ó  Eð  	Eß—f¡TÐ*?×%@Ò%@ÉÐNj×IkÒIkð ×+Ñ+°fÐ+Ó=Ð=Ù×ÒÜÔ1Ó2Ð2Ø×5×5Ð5‰RÐ<dÐfkÐ;l€FØ×$Ò$Ñ. vÑ.Ð.r   c               ó    € V ^8„  d   QhRRRR/# rY   r   )r   s   "r   r   r   ”   s   € ÷ 
ñ 
Ð0ð 
°Sñ 
r   c                ó¼   € ^ RI HpHp V! 4       f   \        V 4      # V! 4       V 3p\        P                  V4      pVf   \        \        4       V 4      ;p\        V&   V# )z¦Cached Entra credential: the process-wide default chain when unscoped, the routed profile's own
credential (built from its secret scope) under a HERMES_HOME override.)Úget_hermes_home_overrideÚhermes_home_key)Úhermes_constantsr}   r~   r)   r+   rK   rz   r"   )rZ   r}   r~   ÚkeyÚ
credentials   &    r   Úbuild_credentialr‚   ”   sa   € ÷ KÙÓ!Ò)Ü(¨Ó0Ð0ÙÓ˜fÐ
%€CÜ%×)Ñ)¨#Ó.€JØÒÜ1CÔD[ÓD]Ð_eÓ1fÐfˆ
Ô)¨#Ñ.ØÐr   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r
   rZ   úOptional[EntraIdentityConfig]r1   rI   Ú	overridesr   r   r0   r   )r   s   "r   r   r   ¡   s1   € ÷ cñ cÐ9ð cÀ-ð cÐ^að cÐfyñ cr   c                ót   € V e   V # \        RRT;'       g    RP                  4       ;'       g    \        /VB # )Nr1   r6   r   )r0   r9   r:   )rZ   r1   r…   s   &&,r   Ú_resolve_configr‡   ¡   s9   € ØÒØˆÜÑb e§k k¨r×%8Ñ%8Ó%:×%TÐ%TÔ>TÐbÐXaÑbÐbr   c               ó    € V ^8„  d   QhRRRR/# )r
   Úallow_installr   r   rH   r   )r   s   "r   r   r   §   s   € ÷ 
ñ 
 Dð 
Ð-Eñ 
r   c                óÒ   € \        4       '       d   R# V '       g   RRR\        /#  \        4        R#   \         d*   pR\	        T4      ;'       g    RR\        RT/u Rp?# Rp?ii ; i)zdNone when ``azure.identity`` is importable (lazy-installing if allowed), else ``{"error", "hint"}``.NÚerrorzazure-identity not installedÚhintr!   )r   Ú_LAZY_INSTALL_HINTr"   r   r   )r‰   r!   s   & r   Ú_install_failurerŽ   §   sj   € ä#×%Ò%ÙßØÐ7¸ÔASÐTÐTðmÜÔ!ñ øô ô mØœ˜S›×CÐCÐ%CÀVÔM_ÐafÐhkÐlÕlûðmús   ¦
2 ²A&½A!ÁA&Á!A&rZ   r2   c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r
   r1   rI   rZ   r„   r2   r   r   úCallable[[], str]r   )r   s   "r   r   r   ´   s1   € ÷ qñ q ð qÐA^ð qØ6:ðqØFWñqr   c               ó˜   € \        4       p\        WVR7      p^ RIHpHp V! VP                  \        V4      VP                  4      V4      # )uâ   Zero-arg callable minting a fresh Entra bearer JWT â€” pass as ``OpenAI(api_key=...)``. Scope precedence:
``config.scope`` > ``scope`` kwarg > default. Not picklable: ship the ``EntraIdentityConfig`` and rebuild
in the worker.)r2   )ÚENTRA_IDÚtag_credential_source)r"   r‡   Úagent.credential_sourcer’   r“   Úget_bearer_token_providerr‚   r1   )r1   rZ   r2   r^   r’   r“   s   &$$   r   Úbuild_token_providerr–   ´   sD   € ô
 
!Ó	"€BÜ˜VÐHcÔd€FßGÙ  ×!=Ñ!=Ô>NÈvÓ>VÐX^×XdÑXdÓ!eÐgoÓpÐpr   c               ó$   € V ^8„  d   QhRRRRRR/# )r
   rZ   r0   Útimeout_secondsÚfloatr   rH   r   )r   s   "r   r   r   ¿   s#   € ÷ 1ñ 1Ð,ð 1¸uð 1ÐIañ 1r   c                ó  a aaa€ / o\         P                  ! 4       oR V V3R llo\        P                  ! VV3R lRR7      pVP	                  4        VP                  \        RV4      R7       VP                  4       '       d   R# S# )	uk   ``get_token`` on a daemon thread under a hard deadline â†’ ``{"token"}`` / ``{"error"}`` / None on timeout.c               ó   € V ^8„  d   QhRR/# r$   r   )r   s   "r   r   Ú"_probe_token.<locals>.__annotate__Ä   s   € ÷ 'ñ '�Dñ 'r   c                 ó¦   <€  \        S4      P                  SP                  4      SR &   R#   \         d   p \	        T 4      SR&    Rp ? R# Rp ? ii ; i)Útokenr‹   N)r‚   Ú	get_tokenr1   r   r   )r!   rZ   Úresults    €€r   Ú_probeÚ_probe_token.<locals>._probeÄ   sB   ø€ ð	'Ü.¨vÓ6×@Ñ@ÀÇÁÓNˆF�7‹OøÜô 	'Ü! #›hˆF�7�Oûð	'ús   ƒ', ¬A·AÁAc                 ó&   <€ SP                  S 4      # ©N)Úrun)r¡   Úctxs   €€r   rh   Ú_probe_token.<locals>.<lambda>Ì   s   ø€ ¨S¯W©W°V¬_r   T)ÚtargetÚdaemong{®Gáz„?)ÚtimeoutN)ÚcontextvarsÚcopy_contextÚ	threadingÚThreadÚstartÚjoinÚmaxÚis_alive)rZ   r˜   Úthreadr¡   r¦   r    s   f& @@@r   Ú_probe_tokenr´   ¿   sj   û€ à€FÜ
×
"Ò
"Ó
$€C÷'ñ 'ô ×ÒÕ%<ÀTÔJ€FØ
‡L�L„NØ
‡K�Kœ˜D /Ó2€KÔ3Ø—?‘?×$Ò$ˆ4Ð0¨&Ð0r   r˜   g      $@r‰   c               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r
   r1   rI   rZ   r„   r˜   r™   r‰   r   r…   r   r   r   )r   s   "r   r   r   Ò   s;   € ÷ =ñ =¨-ð =ÐKhð =Ø49ð=ØQUð=à03ð=à8<ñ=r   c               óf  € \        V4      pVe'   RV9   d   \        P                  RVR,          4       R# \        \	        W3/ VB V4      pVf   \        P                  RV4       R# RV9   d    \        P                  RVR,          4       R# \        \        VP                  R4      RR4      4      # )	zúTimeout-bounded probe: can the chain mint a token now? Never raises. ``allow_install=False`` makes it a
strict "is installed?" check for hot paths (CLI startup) where pip must never run. NOT used by
``is_provider_configured()`` (structural, no mint).Nr!   z+azure-identity lazy install unavailable: %sFz-Entra token service probe timed out after %ssr‹   z!Entra credential probe failed: %srž   )rŽ   ÚloggerÚdebugr´   r‡   r   r(   rK   )r1   rZ   r˜   r‰   r…   Úfailurer    s   &$$$,  r   Úhas_azure_identity_credentialsrº   Ò   s›   € ô ˜}Ó-€GØÒØ�GÔÜ�L‰LÐFÈÐPUÍÔWÙÜœ/¨&ÑE¸9ÑEÀÓW€FØ‚~Ü�‰ÐDÀoÔVÙØ�&ÔÜ�‰Ð8¸&À½/ÔJÙÜ”˜Ÿ
™
 7Ó+¨W°dÓ;Ó<Ð<r   c               ó    € V ^8„  d   QhRRRR/# ©r
   rg   r   r   r   )r   s   "r   r   r   ç   s   € ÷ ,ñ ,ˆsð ,�sñ ,r   c                ó^   € \         P                  P                  V R 4      P                  4       # rf   )ÚosÚenvironrK   r9   )rg   s   &r   Ú_envrÀ   ç   s    € Ü�:‰:�>‰>˜$ Ó#×)Ñ)Ó+Ð+r   c               ó    € V ^8„  d   QhRRRR/# r¼   r   )r   s   "r   r   r   ë   s   € ÷ ,ñ ,�cð ,˜cñ ,r   c                óN   € ^ RI Hp V! V 4      ;'       g    RP                  4       # )u  Credential-bearing env read via the profile secret scope so a multiplexed profile never reports
another profile's env-bridged credentials. Unscoped CLI probes (multiplex off) read the process
env through ``get_secret`` itself; a scope-less multiplex caller raises â€” spawn-site bug.)Ú
get_secretr6   )rq   rÃ   r9   )rg   rÃ   s   & r   Ú_scoped_envrÄ   ë   s#   € õ .á�tÓ×"Ð" ×)Ñ)Ó+Ð+r   z7WorkloadIdentityCredential (AZURE_FEDERATED_TOKEN_FILE)c                 ó   € \        R 4      # )rm   ©rÄ   r   r   r   rh   rh   ö   s
   € ÌÐTpÔHqr   z%EnvironmentCredential (client secret)c                 ód   € \        R 4      ;'       d    \        R4      ;'       d    \        R4      # )rk   rl   rj   rÆ   r   r   r   rh   rh   ø   s*   € Œ[Ð*Ó+×uÐu´Ð<QÓ0R×uÐuÔWbÐctÓWuÐur   z-ManagedIdentityCredential (IDENTITY_ENDPOINT)c                 ó>   € \        R 4      ;'       g    \        R4      # )ÚIDENTITY_ENDPOINTÚMSI_ENDPOINT)rÀ   r   r   r   rh   rh   ù   s   € ¼dÐCVÓ>W×>oÐ>oÔ[_Ð`nÓ[oÐ>or   r1   c               ó0   € V ^8„  d   QhRRRRRRRRR	R
RR/# )r
   rZ   r„   r1   rI   r˜   r™   r‰   r   r…   r   r   r@   r   )r   s   "r   r   r   ý   s<   € ÷  ñ  Ð'Dð  ÐWdð  Ø05ð ØMQð à,/ð à4Bñ r   c               óö  € RR/p\        V4      pVe   VR,          VR,          uVR&   VR&   V# \        W3/ VB p V P                  VR&   \        R4      ;p'       d   WuR&   \         UU	u. uF  w  r‰V	! 4       '       g   K  VNK  	  up	pVR	&   \        W4      p
V
f   R
VR R2VR&   RVR&   V# RV
9   d   V
R,          VR&   V# V
P                  R4      pVf   RVR&   V# RVR&   \        VRR4      VR&   V# u up	pi )a  Doctor / preflight diagnostics. Never raises; ``{"ok": False, "error": ...}`` on failure. azure-identity
hides the winning inner credential, so this reports a coarse picture (env sources, token expiry) rather
than a class name; ``AZURE_LOG_LEVEL=DEBUG`` shows the chain.ÚokFNr‹   rŒ   r1   rj   Útenant_id_envÚenv_sourceszToken probe timed out after z.0fÚsz¸DefaultAzureCredential can be slow when the token service is unreachable or when az login state is stale. Try `az login` or set AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_CLIENT_SECRET.rž   zcredential chain exhaustedTÚ
expires_on)rŽ   r‡   r1   rÄ   Ú_ENV_SOURCE_CHECKSr´   rK   r(   )rZ   r1   r˜   r‰   r…   Úinfor¹   rx   ÚlabelÚpresentr    rž   s   &$$$,       r   Údescribe_active_credentialrÖ   ý   s0  € ð ! %˜=€DÜ˜}Ó-€GØÒØ&-¨gÕ&6¸À½Ð#ˆˆW‰�t˜F‘|ØˆÜ˜VÑ8¨iÑ8€FØ—L‘L€Dˆ�MÜÐ.Ó/Ð/€vÖ/Ø &ˆ_ÑÝ7IÔWÑ7I¡^ UÉWÏYŸ5˜5Ñ7IÒW€DˆÑÜ˜&Ó2€FØ‚~Ø6°ÀsÐ6KÈ1ÐMˆˆW‰ðSˆˆV‰ð ˆØ�&ÔØ˜w�ˆˆW‰ØˆØ�J‰J�wÓ€EØ‚}Ø4ˆˆW‰ØˆØ€Dˆ�JÜ  ¨°dÓ;€DˆÑØ€Kùó# Xs   Á*C5Â C5c               ó    € V ^8„  d   QhRRRR/# )r
   Úvaluer   r   r   r   )r   s   "r   r   r   !  s   € ÷ :ñ :˜Sð : Tñ :r   c                óR   € \        V 4      ;'       d    \        V \        4      '       * # )zNTrue when ``value`` is a callable Entra token provider (vs. a string API key).)r*   Ú
isinstancer   )rØ   s   &r   Úis_token_providerrÛ   !  s   € ä�E‹?×9Ð9¤:¨e´SÓ#9Ô9Ð9r   c               ó    € V ^8„  d   QhRRRR/# )r
   rØ   r   r   r   r   )r   s   "r   r   r   &  s   € ÷ ;ñ ; sð ;¨sñ ;r   c                óÞ   € \        V 4      '       d3   V ! 4       p\        V\        4      '       d	   V'       g   \        R4      hV# \        V \        4      '       d   V '       d   V # \        R4      h)a+  Mint a fresh Bearer JWT for a manual HTTP request (calls the provider once). Only for sites building
``Authorization`` outside the OpenAI SDK; the Anthropic SDK can't take a callable, so
:func:`build_bearer_http_client` calls this from an httpx hook. ``ValueError`` on an unusable value/empty token.z#token provider returned empty valuez"no usable api_key / token provider)rÛ   rÚ   r   Ú
ValueError)rØ   rž   s   & r   Úmaterialize_bearer_for_httprß   &  sV   € ô ˜×ÒÙ“ˆÜ˜%¤×%Ò%¯UÜÐBÓCÐCØˆÜ�%œ×Ò§%ØˆÜ
Ð9Ó
:Ð:r   c               ó    € V ^8„  d   QhRRRR/# )r
   Úrequestr   r   r%   r   )r   s   "r   r   r   4  s   € ÷ /ñ / ð /¨ñ /r   c                óX   € \          F  pV P                  P                  VR 4       K!  	  R # r¤   )Ú_AUTH_HEADERSÚheadersÚpop)rá   Úheader_names   & r   Ú_strip_auth_headersrç   4  s    € ß$ˆØ�‰×Ñ˜K¨Ö.ó %r   Úsends_as_api_keyc               ó(   € V ^8„  d   QhRRRRRRRR/# )r
   Útoken_providerr�   rè   zCallable[[str], bool] | NoneÚhttpx_kwargsr   r   r   )r   s   "r   r   r   9  s2   € ÷ Qñ QØ%ðQØ<XðQØqtðQàñQr   c               óˆ   a a€ \        S 4      '       g   \        R4      h^ RIpR VV 3R llpVP                  ! RRRV.//VB # )uð  ``httpx.Client`` minting a fresh Entra bearer JWT per outbound request. The Anthropic SDK computes
``Authorization`` once at construction, so per-request refresh needs a ``request`` hook: mint (cheap â€”
azure-identity caches), strip pre-set auth headers, set ``Authorization: Bearer``. ``httpx_kwargs`` are
forwarded verbatim (``timeout``, ``transport``...). ``sends_as_api_key(token)`` True puts the minted
token in ``x-api-key`` instead (a ``key_cmd`` printing a native Anthropic Console key).zDbuild_bearer_http_client requires a zero-arg callable token providerNc               ó    € V ^8„  d   QhRRRR/# )r
   rá   zhttpx.Requestr   r%   r   )r   s   "r   r   Ú.build_bearer_http_client.<locals>.__annotate__E  s   € ÷ Añ A˜mð A°ñ Ar   c                ó  <€  \        S4      p\	        T 4       Se   S! T4      '       d   YP
                  R&   R# RT 2T P
                  R&   R#   \         d-   p\        P                  R T4       \	        T 4        Rp?R# Rp?ii ; i)u£   Bearer hook: Entra ID token provider returned empty (%s) â€” stripping Authorization headers. Azure will respond 401. Run `hermes doctor` or `az login` to recover.Nú	x-api-keyzBearer ÚAuthorization)rß   rÞ   r·   Úwarningrç   rä   )rá   rž   r!   rè   rê   s   &  €€r   Ú_inject_authÚ.build_bearer_http_client.<locals>._inject_authE  s…   ø€ ð
	Ü/°Ó?ˆEô 	˜GÔ$ØÒ'Ñ,<¸U×,CÒ,CØ+0�O‰O˜KÓ(à18¸¸Ð/@ˆG�O‰O˜OÓ,øô ô 	ô �N‰Nð KàLOôQô   Ô(Ýûð	ús   ƒA ÁBÁ!BÂBÚevent_hooksrá   r   )rÛ   rÞ   ÚhttpxÚClient)rê   rè   rë   rö   ró   s   fd,  r   Úbuild_bearer_http_clientrø   9  sK   ù€ ô ˜^×,Ò,ÜÐ_Ó`Ð`Û÷Añ Að$ �<Š<ÑP Y°°Ð$?ÐPÀ<ÑPÐPr   )rñ   ÚauthorizationzApi-Keyzapi-keyz	X-Api-Keyrð   r¤   )r:   r0   rø   r‚   r–   rÖ   rº   r   rÛ   rß   r-   )3Ú__conditional_annotations__rS   Ú
__future__r   r   r   r«   Ú	functoolsÚloggingr¾   r­   Údataclassesr   Útypingr   r   r   r   Ú	getLoggerrO   r·   r:   r   r   r�   rã   r   r"   r-   r0   Ú	lru_cacher)   r+   rT   rv   rz   r‚   r‡   rŽ   r–   r´   rº   rÀ   rÄ   rÒ   rÖ   rÛ   rß   rç   rø   Ú__all__)rú   s   @r   Ú<module>r     s§  øðô	õ #å Û Û Û Û 	Û Ý !ß 0Ó 0à	×	Ò	˜8Ó	$€ð 9Ð ð +Ð Øh€à‰LÐ)Ó*Ð+Ð,ð ð c€õòõ$!ñ �$Ô÷
ð 
ó ð
ð. ×Ò˜QÔô/ó  ð/ð  *,Ð Ð&Ó +ð-ð õ/õ&
õcõ
ñqÐaeð qØ=A÷qð qõ1ñ&=Ðkoð =Ø<@ð=ØX\÷=ð =õ*,õ,ð ?Ñ@qÐrØ,Ùuðwà4Ñ6oÐpð	Ð ñ Ðgkð  Ø8<ð ØTX÷ ð  õH:õ
;õ/ð
QØ[_÷QòB‚r   