
    j\F                      d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	m
Z
mZ  ej                  e      ZddlmZ ddlmZmZmZmZ ddlmZ dd	lmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z* dd
l+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2m3Z3 d/d0dZ4d1dZ5d2dZ6d3dZ7d4dZ8d5dZ9d5dZ:d6dZ;d7d8dZ<d9dZ=h dZ>d:dZ?	 	 	 	 	 	 	 	 d;dZ@dddd	 	 	 	 	 	 	 	 	 	 	 	 	 d<dZAd7d=dZB	 	 d>	 	 	 	 	 	 	 	 	 d?dZCd@dZDdAdZEdBd ZFd4d!ZGddd"	 	 	 	 	 dCd#ZHdDd$ZIdEd%ZJddd&	 	 	 	 	 	 	 dFd'ZKddd&	 	 	 	 	 	 	 dGd(ZLdddd)	 	 	 	 	 	 	 	 	 	 	 dHd*ZMddd&	 	 	 	 	 	 	 	 	 	 	 dId+ZNddddd,	 	 	 	 	 	 	 	 	 dJd-ZOdKd.ZPy)LzGShared runtime provider resolution for CLI, gateway, cron, and helpers.    )annotationsN)urlparse)AnyDictOptional)auth)CredentialPoolPooledCredentialget_custom_provider_pool_key	load_pool)
get_secret)	AuthErrorDEFAULT_CODEX_BASE_URLDEFAULT_QWEN_BASE_URLDEFAULT_XAI_OAUTH_BASE_URLPROVIDER_REGISTRY_agent_key_is_usableformat_auth_errorresolve_provider resolve_nous_runtime_credentials!resolve_codex_runtime_credentials%resolve_xai_oauth_runtime_credentials resolve_qwen_runtime_credentials(resolve_gemini_oauth_runtime_credentials$resolve_api_key_provider_credentials-resolve_external_process_provider_credentialshas_usable_secret)get_compatible_custom_providersload_config)OPENROUTER_BASE_URL)base_url_host_matchesbase_url_hostnameenv_intc                &    t        | |      }||S |S )a  Profile-scoped replacement for ``os.getenv`` on credential/provider reads.

    Routes through the secret scope (Workstream A): identical to ``os.getenv``
    when multiplexing is off, scope-aware (and fail-closed on an unscoped read)
    when on. Genuinely-global vars are handled inside ``get_secret`` and still
    read ``os.environ``. Keeps the ``(name, default) -> str`` contract every
    call site here already relies on.
    )_get_secret)namedefaultvals      Z/home/cube/projects/richard/.worktrees/nutricoach-v140-impl/hermes_cli/runtime_provider.py_getenvr*   '   s     dG
$C/3.w.    c                ^    | j                         j                         j                  dd      S )N -)striplowerreplacevalues    r)   _normalize_custom_provider_namer4   4   s$    ;;= ((c22r+   c                P    | xs dj                         j                  d      }|dv S )N .>   ::10.0.0.0	localhost	127.0.0.1)r0   rstrip)hosths     r)   _loopback_hostnamer?   8   s+    	##C(A<<<r+   c                   |xs dj                         j                         }| xs dj                         }|sy|dk(  ry	 ddlm}  ||      dk(  ry	 t        |d      ryt        t        |            S # t        $ r Y ,w xY w)u  Decide whether ``model.base_url`` may back bare ``custom`` runtime resolution.

    GitHub #14676: the model picker can select Custom while ``model.provider`` still reflects a
    previous provider. Reject non-loopback URLs unless the YAML provider is already ``custom``
    (or one of the local-server aliases that resolve to ``custom`` — ollama, vllm, llamacpp, …),
    so a stale OpenRouter/Z.ai base_url cannot hijack local ``custom`` sessions.
    r6   FcustomTr   r   openrouter.ai)r/   r0   hermes_cli.authr   	Exceptionr!   r?   r"   )cfg_base_urlcfg_providercfg_provider_normbu_resolve_providers        r)   ,_config_base_url_trustworthy_for_bare_customrK   =   s     &+224::<

"	#	#	%BH$
I./8; < R1/344	  s   A5 5	B Bc                6   | xs dj                         j                         j                  d      }t        |       }|dk(  ry|dk(  ryt	        |      j
                  j                  d      }|j                  d      s|j                  d      ry|d	k(  rd
|v ryy)u  Auto-detect api_mode from the resolved base URL.

    - Direct api.openai.com endpoints need the Responses API for GPT-5.x
      tool calls with reasoning (chat/completions returns 400).
    - Third-party Anthropic-compatible gateways (MiniMax, Zhipu GLM,
      LiteLLM proxies, etc.) conventionally expose the native Anthropic
      protocol under a ``/anthropic`` suffix — treat those as
      ``anthropic_messages`` transport instead of the default
      ``chat_completions``.
    - Kimi Code's ``api.kimi.com/coding`` endpoint also speaks the
      Anthropic Messages protocol (the /coding route accepts Claude
      Code's native request shape).
    r6   /zapi.x.aicodex_responseszapi.openai.comz
/anthropicz/anthropic/v1anthropic_messageszapi.kimi.comz/codingN)r/   r0   r<   r"   r   pathendswith)base_url
normalizedhostnamerP   s       r)   _detect_api_mode_for_urlrU   [   s     .b'')//188=J *H: ## J$$++C0D}}\"dmmO&D#>!i:&=#r+   c                   t        |       }|syt        d |j                  d      d   D              ry|dv sd|v ry|j                  d      D cg c]  }|s|	 }}|r"|d   dv r|j                  d       |r|d   dv rt	        |      d	k  ry|d
   }dj                  d |D              j                         }|r|d   j                         sy|dv ry| d}t        |d      xs dj                         S c c}w )u_  Look up `<VENDOR>_API_KEY` in the env, derived from the base URL host.

    Examples:
        https://api.deepseek.com/v1   → DEEPSEEK_API_KEY
        https://api.groq.com/openai/v1 → GROQ_API_KEY
        https://api.mistral.ai/v1     → MISTRAL_API_KEY
        https://generativelanguage.googleapis.com/v1beta/openai/ → GOOGLEAPIS_API_KEY

    Returns the env value (stripped) or "". Never returns env vars whose names
    are already explicitly checked elsewhere — those are handled by their own
    host-gated paths (OPENAI/OPENROUTER/OLLAMA).

    The vendor label is the *registrable* portion of the hostname: strip
    ``api.`` / ``www.`` prefixes, then take the second-to-last label
    (``api.deepseek.com`` → ``deepseek``). Falls back to "" for hostnames
    that don't yield a usable vendor label (IPs, loopback, single-label
    hosts).
    r6   c              3  <   K   | ]  }|j                           y wN)isdigit.0chs     r)   	<genexpr>z(_host_derived_api_key.<locals>.<genexpr>   s     
:"9B2::<"9s   r7   )r:   :r   )apiwww   c              3  D   K   | ]  }|j                         r|nd   yw)_N)isalnumrZ   s     r)   r]   z(_host_derived_api_key.<locals>.<genexpr>   s     Efbjjl3fs    )OPENAI
OPENROUTEROLLAMA_API_KEY)
r"   anysplitpoplenjoinupperisalphar*   r/   )rR   rT   lbllabelsvendor	sanitizedenv_names          r)   _host_derived_api_keyrw   w   s   & !*H

:(.."5b"9
::>!SH_%^^C080cCc0F8
VAY.0

1 VAY.0
6{Q BZFEfEEKKMIIaL00266H%HHb!'R..005 9s   C:C:c                   | sy	 ddl }| j                  d      }|j                  d      s|dz  }|j                  |dz   d      }|j                  rG|j                         j                  d	g       }t        |      d
k(  r|d   j                  dd      }|r|S y# t        $ r!}t        j                  d| |       Y d}~yd}~ww xY w)zFQuery a local server for its model name when only one model is loaded.r6   r   NrM   z/v1z/models   )timeoutdata   idz$Auto-detect model from %s failed: %s)
requestsr<   rQ   getokjsonrn   rE   loggerdebug)rR   r~   urlrespmodelsmodel_idexcs          r)   _auto_detect_local_modelr      s    Looc"||E"5LC||C)OQ|777YY[__VR0F6{a!!9==r2#O
 	  L 	;XsKK	Ls   BB 	C#B??Cc                    t               } | j                  d      }t        |t              rt        |      }|j                  d      s|j                  d      r|d   |d<   |j                  d      xs dj	                         }|j                  d      xs dj	                         }d|v xs d|v }| }|r|r|rt        |      }|r||d<   |S t        |t              r"|j	                         rd|j	                         iS i S )Nmodelr'   r6   rR   r:   r;   )r   r   
isinstancedictr/   r   str)config	model_cfgcfgr'   rR   is_localis_fallbackdetecteds           r)   _get_model_configr      s    ]F

7#I)T"9owwy!cggg&6 \C	N779%+224GGJ'-2446(*EkX.E!k/9H!)I
)S!ioo&79??,--Ir+   c                    | xs dj                         j                         }|xs dj                         j                         }|sy|dk(  r|dk(  xs |j                  d      S ||k(  S )aT  Check whether a persisted api_mode should be honored for a given provider.

    Prevents stale api_mode from a previous provider leaking into a
    different one after a model/provider switch.  Only applies the
    persisted mode when the config's provider matches the runtime
    provider (or when no configured provider is recorded).
    r6   TrA   custom:)r/   r0   
startswith)providerconfigured_providernormalized_providernormalized_configureds       r)   $_provider_supports_explicit_api_moder      st     $>r00288:06B==?EEG h&$0_4I4T4TU^4__ $777r+   c                h   t        | j                  d      xs d      j                         j                         }t	        | j                  d            }|rt        d|      r|S t        | j                  d      xs d      j                         }|sy	 ddlm}  |||	      S # t        $ r Y yw xY w)
Nr   r6   api_modecopilotr'   chat_completionsr   )copilot_model_api_mode)api_key)	r   r   r/   r0   _parse_api_moder   hermes_cli.modelsr   rE   )r   r   r   configured_mode
model_namer   s         r)   _copilot_runtime_api_moder      s    immJ7=2>DDFLLN%immJ&?@O?	K^_Y]]9-34::<J!"<%j'BB "!"s   B% %	B10B1>   rN   bedrock_converser   codex_app_serverrO   c                t    t        | t              r(| j                         j                         }|t        v r|S y)z@Validate an api_mode value from config. Returns None if invalid.N)r   r   r/   r0   _VALID_API_MODES)rawrS   s     r)   r   r     s2    #sYY[&&(
))r+   c                    |s|S | dvr|S t        |j                  d      xs d      j                         j                         }|dk(  ry|S )u  Optional opt-in: rewrite api_mode → "codex_app_server" for OpenAI/Codex
    providers when the user has explicitly enabled that runtime via
    `model.openai_runtime: codex_app_server` in config.yaml.

    Default behavior is preserved: when the key is unset, "auto", or empty,
    this function is a no-op. Only providers in {"openai", "openai-codex"}
    are eligible — other providers (anthropic, openrouter, etc.) cannot be
    rerouted through codex.

    Returns the (possibly-rewritten) api_mode.>   openaiopenai-codexopenai_runtimer6   r   )r   r   r/   r0   )r   r   r   runtimes       r)   %_maybe_apply_codex_app_server_runtimer     sV      11)-- 017R8>>@FFHG$$!Or+   )r   pooltarget_modelc           	     2   |xs
 t               }|xs |j                  d      xs d}t        |dd       xs t        |dd       xs dj                  d      }t        |dd       xs t        |dd      }d}	| d	k(  rd
}	|xs t        }n<| dk(  rd
}	|xs t
        }n)| dk(  rd}	|xs t        }n| dk(  r
d}	|xs d}n| dk(  r-d}	t        j                  |       }
|xs |
r|
j                  nd}n| dk(  rd}	t        |j                  d      xs d      j                         j                         }d}|dk(  r;t        |j                  d      xs d      j                         j                  d      }|xs |xs d}nF| dk(  r|xs t        }n5| dk(  rd
}	n,| dk(  rd}	n#| dk(  r0t        |t        |dd            }	|xs t        d   j                  }n| dk(  rt        |j                  d      xs d      j                         j                         }|dk(  r]t        |j                  d      xs d      j                         j                  d      }|r|}t        |j                  d            }|r|}	|r|	dk7  r	 ddlm}  ||      }|r|}	|	dk(  r-t%        j&                  dd|      }nt        |j                  d      xs d      j                         j                         }t        j                  |       }
|
xr- |j                  d      |
j                  j                  d      k(  }|| k(  rA|r?t        |j                  d      xs d      j                         j                  d      }|r|}t        |j                  d            }| dv rddlm}  || |      }	n |rt+        | |      r|}	nt-        |      }|r|}	|	dk(  r| dv rt%        j&                  dd|      }t/        | |	|      }	| |	||t        |d d!      ||d"S # t"        $ r d }Y w xY w)#Nr'   r6   runtime_base_urlrR   rM   runtime_api_keyaccess_tokenr   r   rN   	xai-oauth
qwen-oauthgoogle-gemini-clizcloudcode-pa://googleminimax-oauthrO   	anthropicr   https://api.anthropic.com
openrouterxainousr   azure-foundryr   r   azure_foundry_model_api_mode/v1/?$   opencode-goopencode-zenopencode_model_api_mode)r   r   r   sourcer   )r   r   rR   r   r   credential_poolrequested_provider)r   r   getattrr<   r   r   r   r   inference_base_urlr   r/   r0   r    r   r   r   r   rE   resubr   r   rU   r   )r   entryr   r   r   r   effective_modelrR   r   r   pconfigrG   rF   r   r   inferredr   pool_url_is_defaultr   r   s                       r)    _resolve_runtime_from_pool_entryr   1  s7    0.0I $Ey}}Y'?E2O148bGE:W[<\b`bjjknoHe.5[XZ9[G!H>!$55	[	 $99	\	!%44	(	(%66	_	$
 (#''1Ng : :2	[	 '9==4:;AACIIK;&y}}Z8>B?EEGNNsSLJ8J/J	\	!22	U	$	V	%	Y	,YGXZ\8]^N0;NN	_	$9==4:;AACIIK?*y}}Z8>B?EEGNNsSL'-immJ.GHO*
 x+?? J7H #++vviX6H!)--
";"ArBHHJPPR
 $''1%h(//#*>'B\B\BcBcdgBh*h(*/By}}Z8>B?EEGNNsSL'))--
*CD66 B.xIH!EhPc!d&H
 09H# ''H8W,W66)R2 5H	H
 %620 g    s   ?P PPc                n   | r.| j                         r| j                         j                         S t               }|j                  d      }t	        |t
              r.|j                         r|j                         j                         S t        dd      j                         j                         }|r|S y)z=Resolve provider request from explicit arg, config, then env.r   HERMES_INFERENCE_PROVIDERr6   auto)r/   r0   r   r   r   r   r*   )	requestedr   rG   env_providers       r)   resolve_requested_providerr     s    Y__& &&((!#I==,L,$););)=!!#))++ 6;AACIIKLr+   c                   t        | |      }|sy	 t        |      }|j                         sy|j                         }|yt	        |dd      xs t	        |dd      }|sy||xs t        |       xs d| |d| |dS # t        $ r Y yw xY w)	zXCheck if a credential pool exists for a custom endpoint and return a runtime dict if so.provider_nameNr   r   r6   r   zpool:)r   r   rR   r   r   r   )r   r   has_credentialsselectr   rU   rE   )rR   provider_labelapi_mode_overrider   pool_keyr   r   pool_api_keys           r)   _try_resolve_from_custom_poolr     s     ,HMRH"##%=u&7>d'%Q_acBd&)e-Eh-OeSe #hZ(#
 	
  s"   A= A= A=  A= =	B	B	c                n    dD ]0  }| j                  |      }t        |t              s%|dkD  s+||d<    y y)aq  Propagate a per-provider output cap onto the resolved runtime dict.

    Accepts ``max_output_tokens`` or ``max_tokens`` on a ``custom_providers``
    entry so a provider block can pin its own output limit. Gateway and CLI
    map this onto ``AIAgent.max_tokens`` only when the top-level
    ``model.max_tokens`` isn't set, so the documented global key still wins.
    )max_output_tokens
max_tokensr   r   N)r   r   int)r   result_k_vs       r)   _lift_max_output_tokensr     s9     2YYr]b#26*,F&'	 2r+   c           	     
   t        | xs d      }|sy |dk(  ry |dk7  rM|j                  d      s<	 t        j                  |      }|xs dj	                         j                         |k(  ry t               }|j                  d      }t        |t              r|j                         D ]  \  }}t        |t              st        |      }t        |j                  dd      xs d      j	                         }|rt        |d      j	                         nd}	|	s-t        |j                  dd      xs d      j	                         }	|||d| hv r|j                  d      xs( |j                  d	      xs |j                  d
      xs d}
|
r|j                  d|      |
j	                         |	|j                  dd      d}|j                  d      }t        |t              rt        |      |d<   t        |j                  d      xs |j                  d            }|r||d<   t        ||       |c S |j                  dd      }|st        |      }|||d| hv s|j                  d      xs( |j                  d	      xs |j                  d
      xs d}
|
s||
j	                         |	|j                  dd      d}|j                  d      }t        |t              rt        |      |d<   t        |j                  d      xs |j                  d            }|r||d<   t        ||       |c S  |j                  d      }t        |t              rt         j#                  d       y t%        |      }|sy |D ]  }t        |t              s|j                  d      }|j                  d
      }
t        |t              rt        |
t              sXt        |      }d| }t        |j                  dd      xs d      j	                         }|rt        |      nd}|rd| nd}|||||hvr|j	                         |
j	                         t        |j                  dd      xs d      j	                         d}t        |j                  dd      xs d      j	                         }|r||d<   |r||d<   |j                  d      }t        |t              rt        |      |d<   t        |j                  d            }|r||d<   t        |j                  dd      xs d      j	                         }|r||d<   t        ||       |c S  y # t        $ r Y w xY w)Nr6   r   rA   r   	providerskey_envr   r`   r   rR   r&   default_model)r&   rR   r   r   
extra_bodyr   	transportcustom_providerszcustom_providers in config.yaml is a dict, not a list. Each entry must be prefixed with '-' in YAML. Run 'hermes doctor' for details.provider_key)r&   rR   r   r   )r4   r   auth_modr   r/   r0   r   r   r   r   r   itemsr   r*   r   r   r   warningr   )r   requested_norm	canonicalr   r   ep_namer   	name_normr   resolved_api_keyrR   r   r   r   display_namedisplay_normr   r&   menu_keyr   provider_key_normprovider_menu_keyr   s                          r)   _get_named_custom_providerr    s   45G5M2NN" !.*C*CI*N	 11.AI R&&(..0NB]F 

;'I)T"'oo/NGUeT*7@I%))Ir28b9??AG?Fww399;B##&uyyB'?'E2#F#L#L#N '9	{6K!LL 99U+^uyy/?^599ZCX^\^ %		&' :$,NN$4#3!&?B!?	F "'<!8J!*d3/3J/?|,  /uyy/D/^		R]H^_H-5z*+E6:!M 99VR0L>|L!lLGL>BZ%[[$yy/b599U3CbuyyQ[G\b`bH$0(0(8'7%*YY%C	" &+YY|%<
%j$737
3CF<0#2599Z3H3bEIIVaLb#c#19F:./v>%u 0z zz"45"D)/	

 6v>!%&yy 99Z($$Jx,E3D9	YK(599^R8>B?EEGMY;LI_a=Ng&7%89TV)X7HJ[!\\JJL (599Y39r:@@B

 eii	2.4"5;;= 'F9%1F>"YY|,
j$'#'
#3F< "599Z#89!)F:7B/526<<>
(F7Ov.E "H C  		s   U 	U U c                <    	 t        |       duS # t        $ r Y yw xY w)u~  Return True when config defines a custom provider matching the request.

    Thin public wrapper around :func:`_get_named_custom_provider` so other
    modules (e.g. the cronjob tool) can decide whether a provider name will
    actually resolve to a configured ``providers:`` / ``custom_providers:``
    entry — without reaching into a private helper or duplicating the scan.
    NF)r  rE   )r   s    r)   has_named_custom_providerr    s*    )*<=TII s    	c                   t        |       }|sy	 t               }|j                  d      }t	        |t
              r|j                         D ]x  \  }}t	        |t
              s|j                  d      xs( |j                  d      xs |j                  d      xs d}t        |      |k(  sadt        t        |             c S  	 t        |      }|xs g D ]r  }t	        |t
              s|j                  d      }t	        |t              r|j                         sFt        |j                  d            |k(  sddt        |       c S  y# t        $ r Y yw xY w# t        $ r d}Y w xY w)	uD  Map an endpoint URL back to its canonical ``custom:<name>`` menu key.

    Returns the ``custom:<normalized-name>`` slug of the first ``providers:``
    / ``custom_providers:`` entry whose base_url matches, or ``None`` when no
    entry owns the URL.

    Session persistence stores the agent's *resolved* provider, and for every
    named custom endpoint that is the literal string ``"custom"`` — the entry
    name is lost, and the api_key is deliberately never persisted. The
    endpoint URL is the one durable fact that survives the round-trip, so
    this reverse lookup lets persist/rebuild paths recover the entry identity
    (and with it key_env/api_key/api_mode resolution via
    :func:`_get_named_custom_provider`) instead of failing with
    ``auth_unavailable`` or silently rebuilding with placeholder credentials.
    Nr   r`   r   rR   r6   r   r&   )_normalize_base_url_for_matchr   rE   r   r   r   r   r4   r   r   r/   )	rR   targetr   r   r   r   	entry_urlr   r&   s	            r)   find_custom_provider_identityr    sc     +84F 

;'I)T"'oo/NGUeT*		% SEIIe$4S		*8MSQS  -Y76A !@W!N OPP 0 :6B "'R'%&yy $$DJJL(:)>?6I<TBCDD ( 7       s#   
E E 	EEE+*E+)rR   config_providerc                   | rt        |       }|r|S t        |xs d      j                         }|s5	 t        t               j	                  d      xs d      j                         }|s.t        j                  j	                  dd      j                         }t        |      }|r|dv ry	 t        |      |j                  d      r|S d| S 	 y# t
        $ r d}Y uw xY w# t
        $ r Y yw xY w)u  Recover a routable ``custom:<name>`` identity for a bare custom provider.

    The bare string ``"custom"`` is the *resolved billing class* shared by
    every named ``providers:`` / ``custom_providers:`` entry — it is NOT a
    routable provider identity (``resolve_runtime_provider("custom")`` falls
    through to the OpenRouter default URL with no api_key, which surfaces to
    the user as "No LLM provider configured").

    Any code path that persists or restores a session's provider override
    must run the resolved provider through this helper so a bare ``"custom"``
    is upgraded back to its durable ``custom:<name>`` menu key. Two recovery
    sources, in priority order:

    1. ``base_url`` — reverse-lookup the entry that owns the endpoint URL
       (the one fact that always survives the persistence round-trip when a
       URL was recorded).
    2. ``config_provider`` — the active ``config.model.provider`` (or its
       ``provider``/``HERMES_INFERENCE_PROVIDER`` equivalent). When the agent
       was built without a base_url on the override (the recurring
       Desktop/TUI regression vector), the configured provider is the only
       durable identity left, so fall back to it when it names a real entry.

    Returns ``custom:<name>`` when a routable identity is recovered, else
    ``None`` (caller keeps whatever it had — bare ``"custom"`` only as a last
    resort, e.g. a genuine ad-hoc endpoint with no config entry).
    r6   r   r   >   r   rA   r   Nr   )r  r   r/   r   r   rE   osenvironr4   r  r   )rR   r  identity	candidatecandidate_norms        r)   canonical_custom_identityr    s   @ 0:O O)r*002I	-/33J?E2FLLNI JJNN#>CIIK	4Y?N^/OO%i0<((3%%^,-- = %  	I	   s)   4C )C C CC	C+*C+c                v    t        | xs d      j                         j                  d      j                         S )Nr6   rM   )r   r/   r<   r0   r2   s    r)   r
  r
    s.    u{!!#**3/5577r+   c                f    | j                  d      }t        |t              r|si S dt        |      iS )Nr   )r   r   r   )custom_providerr   s     r)   "_custom_provider_request_overridesr    s3     $$\2Jj$'z	$z*++r+   explicit_api_keyexplicit_base_urlc           
     j   | xs dj                         j                         }|r|dk7  r	 ddlm}  ||      dk(  rd}|dk(  r|r|j                         j                  d      }t        |dd       }|rd|d<   |S t        |d      xs t        |d	      }t        |d
      }|xs dj                         |rt        dd      j                         nd|rt        dd      j                         ndt        |      g}	t        d |	D        d      xs d}
dt        |      xs d||
d| dS t        |       }|sy |xs dj                         xs |j                  dd      j                  d      }|sy t        |d|j                  d      |j                  d            }|rs|j                  d      }|r||d<   t        |j                  d      t              r|d   |d<   t!        |      }|r%i t#        |j                  d      xs i       ||d<   |S t        |d      xs t        |d	      }t        |d
      }|xs dj                         t%        |j                  dd      xs d      j                         t        t%        |j                  dd      xs d      j                         d      j                         |rt        dd      j                         nd|rt        dd      j                         ndt        |      g}	t        d |	D        d      }
d|j                  d      xs t        |      xs d||
xs dd|j                  d|        d}|j                  d      r|d   |d<   t        |j                  d      t              r|d   |d<   t!        |      }|r||d<   |S # t        $ r Y sw xY w)Nr6   rA   r   rB   rM   zdirect-aliasr   
openai.comopenai.azure.comrC   OPENAI_API_KEYOPENROUTER_API_KEYc              3  8   K   | ]  }t        |      s|  y wrX   r   )r[   cs     r)   r]   z0_resolve_named_custom_runtime.<locals>.<genexpr>Q  s     C*1.?.BQ*   no-key-requiredr   r   r   rR   r   r   r   rR   r   r&   r   r   r   request_overridesr   r   c              3  8   K   | ]  }t        |      s|  y wrX   r#  r[   r  s     r)   r]   z0_resolve_named_custom_runtime.<locals>.<genexpr>  s     b/A)EVW`EaI/Ar%  zcustom_provider:r   r   rR   r   r   )r/   r0   rD   r   rE   r<   r   r!   r*   rw   nextrU   r  r   r   r   r  r   r   )r   r  r  r   rJ   rR   pool_result_da_is_openai_url_da_is_openrouterapi_key_candidatesr   r  r   r(  _cp_is_openai_url_cp_is_openrouterr   s                    r)   _resolve_named_custom_runtimer3  $  s>    ).B557==?N.H4	M 0H<!) !&7$**,33C8 4HhM$2K!3HlK  COdem  pB  PC3HoN#**,:KW%r*002QS:KW)2.446RT "(+	
 C*C
   	
 !0:P>P $"4
 	
 11CDO 
	 b'') 	/z2.fSk   0(ODWDWXbDc  tC  tG  tG  HN  tO  PK %((1
#-K o))*=>D/>?R/SK+,>O0{':;ArB0#0K+, /,G~K`aik}K~//J		R&&(O	2.4"5;;=O''	26<"=CCErJPPR 7H!2	&	,	,	.b6G%r	*	0	0	2b 	h' b/AbdfgG #''
3 #H-//$_%8%8AS%T$UVF 7#)'2w/%%&9:C@&56I&J"#:?K&7"#MG  		s   N% %	N21N2c           	     R   t               }t        |j                  d      t              r|j                  d      nd}t        |j                  d      t              r|j                  d      nd}d}dD ]F  }|j                  |      }t        |t              s%|j	                         s6|j	                         } n | xs dj	                         j                         }	|j	                         j                         }|	r|	dk7  r	 ddlm}
  |
|	      dk(  rd}	t        dd      j	                         }t        d	d      j	                         }d
}|j	                         r$|s"|	dk(  r
|r|dk(  rd}n|	dk(  rt        ||      rd}|xs dj	                         xs$ |xs  |r|j	                         ndxs
 |xs t        j                  d      }t        |d      }|xs* |	dk(  xr# |xs ||k(  xr ||xs dj                  d      k(  }|r|t        d      t        d      g}nbt        |d      }t        |d      }t        |d      }||r|nd|rt        d      nd|s|rt        d      nd|rt        d      ndt        |      g}t        d |D        d      }|s|rdnd}|	dk(  rdnd}|dk(  r4|r2t!        ||t#        |j                  d            |	dk7  r| nd       }|r|S |dk(  r|s|sd}|t#        |j                  d            xs t%        |      xs d|||dS # t        $ r Y w xY w)NrR   r6   r   )r   r`   rA   r   rB   r    CUSTOM_BASE_URLFr   TrM   rC   r   r!  r   z
ollama.comr  r  OLLAMA_API_KEYc              3  n   K   | ]-  }t        |      st        |xs d       j                          / yw)r6   N)r   r   r/   r*  s     r)   r]   z._resolve_openrouter_runtime.<locals>.<genexpr>  s.     j7I)M^_hMiY_"		#	#	%7Is   5"5explicitz
env/configr   r   r&  r   r+  )r   r   r   r   r/   r0   rD   r   rE   r*   rK   r    r<   r!   rw   r,  r   r   rU   )r   r  r  r   rF   rG   cfg_api_keykvr   rJ   env_openrouter_base_urlenv_custom_base_urluse_config_base_urlrR   _is_openrouter_url_is_openrouter_contextr0  _is_ollama_url_is_openai_url_is_openai_azurer   r   effective_providerr-  s                            r)   _resolve_openrouter_runtimerE    s    "#I0:9==;TVY0Z9==,`bL0:9==;TVY0Z9==,`bLKMM!a!'')'')K	  
 ).B557==?N%%'--/L .H4	M 0H<!) &&;R@FFH!"3R8>>@
  $5V#<6#9&*#x',X,-
 #' 
	 b'') 		$7L R	 #	 fSk  /xI 0 ,& 	D$K4K(K	D06B>>sCC 
 ()$%
 2(LI1(LI1(<NO /[R.<W%&XZ/=AQW%&XZ.@W)*XZ
 "(+
 j7Ij
G
 -0AZF &4x%?\ X%( 4(/)--
:S*T0>(0J,PT
 X%g>P# '#IMM*$=> #H- K  		s   L 	L&%L&)r  r  r   c           	        t        |xs d      j                         }t        |xs d      j                         j                  d      }t        |j                  d      xs d      j                         j	                         }d}d}d}	i }
|dk(  rt        |j                  d      xs d      j                         j                  d      }t        |j                  d            xs d}t        |j                  d	      xs d      j                         j	                         xs d}	|j                  d
      }t        |t              r|}
t        |xs |j                  d      xs d      j                         }|r|dk7  r	 ddlm	}  ||      }|r|}t        dd      j                         j                  d      }|xs |xs |}|st        d      |dk(  rt        j                  dd|      }|	dk(  r|r|}d}d}nT	 ddlm}m}m} t        |
j                  d      xs d      j                         xs |}	  ||      } ||      }|}d}d}i }|dk(  r3t        |
j                  d      xs d      j                         }|r||d<   d||||||| dS |}|s	 ddlm}  |d      xs d}|st        dd      j                         }|st        d      |s|rdnd}d|||d|| d S # t        $ r d}Y gw xY w# t        $ r}t        d| d      |d}~ww xY w# t&        $ r}t        t        |            |d}~ww xY w# t        $ r d}Y w xY w)!a  Resolve an Azure Foundry runtime entry.

    Reads ``model.base_url`` + ``model.api_mode`` from config.yaml (or
    explicit overrides), pulls the API key from ``.env`` / env var, and
    strips a trailing ``/v1`` for Anthropic-style endpoints because the
    Anthropic SDK appends ``/v1/messages`` internally.

    When ``model.auth_mode == "entra_id"`` (and the model is OpenAI-style),
    the returned ``api_key`` is a zero-arg callable produced by
    :func:`agent.azure_identity_adapter.build_token_provider` rather than
    a string. Downstream code that constructs an OpenAI SDK client passes
    this through unchanged (the SDK accepts ``Callable[[], str]`` for
    ``api_key`` and calls it before every request). Code paths that need
    a string (logging, manual HTTP probes, header injection) must use the
    helpers in ``agent.azure_identity_adapter``.

    Raises :class:`AuthError` when required values are missing.
    r6   rM   r   r   r   r   rR   r   	auth_modeentrar'   rO   r   r   NAZURE_FOUNDRY_BASE_URLzpAzure Foundry requires a base URL. Set it via 'hermes model' or the AZURE_FOUNDRY_BASE_URL environment variable.r   entra_idr8  )EntraIdentityConfigSCOPE_AI_AZURE_DEFAULTbuild_token_providerzAzure Foundry Entra ID auth requires the 'azure-identity' package. Install it with: pip install azure-identity (import failed: )scope)rO  )r   )r   r   rR   r   rG  rH  r   r   )get_env_valueAZURE_FOUNDRY_API_KEYa  Azure Foundry requires an API key. Set AZURE_FOUNDRY_API_KEY in ~/.hermes/.env or run 'hermes model' to configure. To use keyless Microsoft Entra ID auth instead, set model.auth_mode: entra_id in config.yaml (or pick 'Microsoft Entra ID' in 'hermes model').r   )r   r   rR   r   rG  r   r   )r   r/   r<   r   r0   r   r   r   r   r   rE   r*   r   r   r   agent.azure_identity_adapterrK  rL  rM  ImportErrorhermes_cli.configrP  )r   r   r  r  r   explicit_base_url_cleanrG   rF   cfg_api_modecfg_auth_mode	cfg_entra_entrar   r   r   env_base_urlrR   r   r   rG  rK  rL  rM  r   rO  entra_configtoken_providerclean_entraconfigured_scoperP  s                                 r)   _resolve_azure_foundry_runtimer_  +  s   4 +1r288:!"3"9r:@@BII#Ny}}Z06B7==?EEGLL%LM "I&9==4:;AACJJ3O&y}}Z'@AWEWIMM+6C)DJJLRRTaXaw'fd#I ,H)--	*BHbIOOQO<+??	F3ODH #L3R8>>@GGLL&F,F,H?
 	
 ++66)R2  
" ,GF!I  IMM'*0b1779 *) 32  "6\!J %GF"I
""9==#9#?R@FFH'7G$ ($ " "4	
 		
 G	7#$;<BG 126<<>7
 	
 -0AZF# 0 S  	H	\  ''*e1. 	   3C)s23:  	G	sT   K*  
K< ;L M *K98K9<	LLL	M &L;;M MMc           
     h   t        |xs d      j                         }t        |xs d      j                         j                  d      }|s|sy | dk(  rt        |j                  d      xs d      j                         j	                         }d}|dk(  r;t        |j                  d      xs d      j                         j                  d      }|xs |xs d}|}|sddlm}	  |	       }|st        d	      dd
||d|dS | dk(  rn|xs t        }|}d }
|sTt               }|j                  dd      }|j                  d      }
|s%|j                  dd      j                  d      xs |}dd||d|
|dS | dk(  rQt        j                  d      xs i }|xsI t        |j                  d      xs t        j                        j                         j                  d      }|xsN t        |t        dt        dd                  r,t        |j                  d      xs d      j                         nd}|j                  d      xs |j                  d      }|sit!        t#        t%        dd                  }|j                  dd      }|j                  d      }|s%|j                  dd      j                  d      xs |}dd||d||dS | dk(  rt'        ||||       S t)        j                  |       }|r<|j*                  dk(  r,d}|j,                  r3t%        |j,                  d      j                         j                  d      }|}|sA| d!v r-t/        |       }|j                  dd      j                  d      }n|xs |j0                  }|}|s@t/        |       }|j                  dd      }|s!|j                  dd      j                  d      }d}| d"k(  rt3        ||      }n6| d#k(  rd}n.t5        |j                  d$            }|r|}nt7        |      }|r|}| ||j                  d      |d|dS y )%Nr6   rM   r   r   rR   r   r   resolve_anthropic_tokenNo Anthropic credentials found. Set ANTHROPIC_TOKEN or ANTHROPIC_API_KEY, run 'claude setup-token', or authenticate with 'claude /login'.rO   r8  r'  r   r   last_refreshrN   r   r   rR   r   r   rd  r   r   r   <   HERMES_NOUS_MIN_KEY_TTL_SECONDS  	agent_keyagent_key_expires_at
expires_atHERMES_NOUS_TIMEOUT_SECONDS15timeout_secondsr   r   r   rR   r   r   rk  r   r   )r   r   r  r  >   kimi-codingkimi-coding-cnr   r   r   )r   r/   r<   r   r0   agent.anthropic_adapterrb  r   r   r   r   get_provider_auth_stateDEFAULT_NOUS_INFERENCE_URLr   maxr#   r   floatr*   r_  r   	auth_typebase_url_env_varr   r   r   r   rU   )r   r   r   r  r  rG   rF   rR   r   rb  rd  credsstaterk  r   env_urlr   r   r   s                      r)   _resolve_explicit_runtimer}    sg    +1r288:-34::<CCCH$5;9==4:;AACIIK;&y}}Z8>B?EEGNNsSL$SS8S"G-/GV 
 $,  "4
 	
 >!$>(>"57Eii	2.G 99^4L$ 99Z4;;C@LH&)  ("4
 	
 6008>B o59912Yh6Y6YZ``biijmn 	 # 
#B A4HI 		+&,"-335
  	 YY56Q%))L:Q
4 %g.KT&R SE ii	2.G<0J$ 99Z4;;C@LH*  $"4
 	
 ?"-1-/	
 	
  ##H-G7$$	1##g66;AACJJ3OG$<<<XF 99Z4;;C@"@g&@&@"8BEii	2.G 99Z4;;C@%y 0GDH(H-immJ.GHO* 4H='H !  , "4
 	
 r+   )r   r  r  r   c                   t        |       }|xs dj                         }|dk(  rhd|v rd|xs dj                         xs6 t        dd      j                         xs t        dd      j                         }dd|j                  d      |d|d	S |d
k(  rt	        |t               |||      }|S t        |||      }|r||d<   |S t        |||      }	t               }
t        |	||
||      }|r|S |	dk7  }|	dk(  rt        |
j                  d      xs d      j                         j                         }t        |
j                  d      xs d      j                         }t        dd      j                         }t        dd      j                         }t        |xs |xs |      }|r|dv rd}t        |xs |      }|dv xr | xr | }	 |rt        |	      nd}|r|j                         r|j!                         }d}|t#        |dd      xs t#        |dd      }|	dk(  rd|b|r`t%        dt'        dd            }t#        |dd      t#        |d d      t#        |d!d      d"}t)        ||      st*        j-                  d#       d}||rt/        |	|||
||$      S |	dk(  rx	 t1        t3        t        d%d&            '      }dd(|j                  dd      j                  d      |j                  d)d      |j                  d*d+      |j                  d,      |d-S |	d0k(  rc	 t9               }d0d1|j                  dd      j                  d      |j                  d)d      |j                  d*d2      |j                  d3      |d4S |	d6k(  rn	 t;               }d6d1|j                  d      xs dj                  d      xs t<        |j                  d)d      |j                  d*d2      |j                  d3      |d4S |	d8k(  rc	 t?               }d8d(|j                  dd      j                  d      |j                  d)d      |j                  d*d9      |j                  d:      |d;S |	d=k(  rRtA        j                  |	      }|r;|jB                  d>k(  r,d?d@l"m#}  |       }|	d|d   |d)   |j                  d*dA      |d	S |	dBk(  rv	 tI               }dBd(|j                  dd      |j                  d)d      |j                  d*dC      |j                  d:      |j                  dDd      |j                  dEd      |dF	S |	dHk(  rtK        |	      }dHd(|j                  dd      j                  d      |j                  d)d      |j                  dId      tM        |j                  dJ      xs g       |j                  d*dK      |dLS |	dk(  rt        |
j                  d      xs d      j                         j                         }d}|dk(  r2|
j                  d      xs dj                         j                  d      }|xs dM}d|j                         v xs |xr d|j                         v }|rd}dND ]O  }t        |
j                  |      xs d      j                         }|s2t        |d      j                         }|sO n |s,t        |
j                  d)      xs d      j                         }|s6t        dd      j                         xs t        dd      j                         }|s%t5        dO      d?dPl'm(}   |        }|st5        dQ      dd||dR|d	S |	dSk(  rEd?dTl)m*}!m+}"m,}#m-}$ |dUv }%|%s |!       st5        dVdWX      t]               j                  dSi       }&|&j                  dY      xs dj                         xs  |#       }' |"       xs dZ}(|&j                  d[i       })d}*|)j                  d\      rN|)j                  d]      r=|)d\   |)d]   d^}*|)j                  d_      r|)d_   |*d`<   |)j                  da      r|)da   |*da<   t        |
j                  db      xs d      j                         }+ |$|+      rdSddc|' ddde|(|'d|df},ndSdgdc|' ddde|(|'|dh},|*r|*|,di<   |,S tA        j                  |	      }|r|jB                  d)k(  rt_        |	      }t        |
j                  d      xs d      j                         j                         }d}||	k(  r2|
j                  d      xs dj                         j                  d      }|xs! |j                  dd      j                  d      }d(}-|	djk(  rta        |
|j                  d)d            }-n|	dkk(  rd1}-nt        |
j                  d      xs d      j                         j                         }.tc        |
j                  dl            }/|	dmv r&d?dnl2m3}0 |xs |
j                  dbd      }1 |0|	|1      }-n |/rti        |	|.      r|/}-ntk        |      }2|2r|2}-|-dk(  r|	dmv rtm        jn                  dod|      }|	|-||j                  d)d      |j                  d*dR      |d	S tq        |||      },||,d<   |,S # t        $ r d}Y w xY w# t4        $ r |d.k7  r t*        j7                  d/       Y w xY w# t4        $ r |d.k7  r t*        j7                  d5       Y lw xY w# t4        $ r |d.k7  r t*        j7                  d7       Y $w xY w# t4        $ r |d.k7  r t*        j7                  d<       Y w xY w# t4        $ r |d.k7  r t*        j7                  dG       Y @w xY w)pa)  Resolve runtime provider credentials for agent execution.

    target_model: Optional override for model_cfg.get("default") when
    computing provider-specific api_mode (e.g. OpenCode Zen/Go where different
    models route through different API surfaces). Callers performing an
    explicit mid-session model switch should pass the new model here so
    api_mode is derived from the model they are switching TO, not the stale
    persisted default. Other callers can leave it None to preserve existing
    behavior (api_mode derived from config).
    r6   r   z	azure.comAZURE_ANTHROPIC_KEYANTHROPIC_API_KEYrO   rM   zazure-explicitr'  r   )r   r   r  r  r   )r   r  r  r   r  )r   r   r   r  r  r   r   rR   OPENAI_BASE_URLr    >   r   rA   T>   r   r   Nr   r   r   rf  rg  rh  ri  rj  rO  )ri  rj  rO  zPNous pool entry agent_key expired/missing, falling through to runtime resolution)r   r   r   r   r   r   rl  rm  rn  r   r   r   portalrk  rp  r   zUAuto-detected Nous provider but credentials failed; falling through to next provider.r   rN   zhermes-auth-storerd  re  zVAuto-detected Codex provider but credentials failed; falling through to next provider.r   zZAuto-detected xAI OAuth provider but credentials failed; falling through to next provider.r   zqwen-cliexpires_at_ms)r   r   rR   r   r   r  r   z@Qwen OAuth credentials failed; falling through to next provider.r   oauth_minimaxr   ))resolve_minimax_oauth_runtime_credentialsoauthr   zgoogle-oauthemail
project_id)	r   r   rR   r   r   r  r  r  r   zIGoogle Gemini OAuth credentials failed; falling through to next provider.zcopilot-acpcommandargsprocess)r   r   rR   r   r  r  r   r   r   )r   api_key_envzNo Azure Anthropic API key found. Set AZURE_ANTHROPIC_KEY or ANTHROPIC_API_KEY, or point key_env/api_key_env in your config.yaml model section at a custom env var.ra  rc  envbedrock)has_aws_credentialsresolve_aws_auth_env_varresolve_bedrock_regionis_anthropic_bedrock_model>   aws-bedrockamazon-bedrockawsamazonr  zNo AWS credentials found for Bedrock. Configure one of:
  - AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY
  - AWS_PROFILE (for SSO / named profiles)
  - IAM instance role (EC2, ECS, Lambda)
Or run 'aws configure' to set up credentials.no_aws_credentials)coderegionzaws-sdk-default-chain	guardrailguardrail_identifierguardrail_version)guardrailIdentifierguardrailVersionstream_processing_modestreamProcessingModetracer'   zhttps://bedrock-runtime.z.amazonaws.comzaws-sdk)r   r   rR   r   r   r  bedrock_anthropicr   r   )r   r   rR   r   r   r  r   guardrail_configr   r   r   r   r   r   )9r   r/   r*   r<   r_  r   r3  r   r}  r   r   r0   boolr   rE   r   r   r   rv  r#   r   r   r   r   r   rw  r   infor   r   r   r   r   rx  rD   r  r   r   listrs  rb  agent.bedrock_adapterr  r  r  r  r   r   r   r   r   r   r   rU   r   r   rE  )3r   r  r  r   r   	_eff_base
_azure_keyazure_runtimecustom_runtimer   r   explicit_runtimeshould_use_poolrG   rF   env_openai_base_urlr<  has_custom_endpointhas_runtime_overrider   r   r   min_ttl
nous_staterz  r   r  rR   _is_azure_endpointtokenhint_keyenv_varrb  r  r  r  r  is_explicit_bedrock_cfgr  auth_source_grr  _current_modelr   r   r   r   r   
_effectiver   s3                                                      r)   resolve_runtime_providerr  l  s   " 4I> #(b//1I[([I-E#**, 8,b17798*B/557 	 $,!((-!&"4
 	
 _,61')-/%
 2-)+N
 /A+,)+H
 "#I0-)+ ,.O<9==4:;AACIIK9==4:;AAC%&7<BBD")*?"D"J"J"L" '"'&

 L,>>"&#$4$I8IJ"88 )'')(( 	&5y"4 $$&0$7 65."5  v%"3"g&GNOG$UK>(/7Mt(T 6J
 (
G<op!3!#5#)  6	=4 %g.KT&R SE #.!IIj"5<<SA 99Y3))Hh7#ii5&8 " >!	=57E*-!IIj"5<<SA 99Y3))H.AB %		. 9&8 " ;	=9;E'-"YYz28b@@EcIc 99Y3))H.AB %		. 9&8  <	=46E(.!IIj"5<<SA 99Y3))Hj9!&?!;&8  ?"#''1w((O;Q=?E$0!*- +))Hg6&8  &&	=<>E/.!IIj"5 99Y3))Hn=!&?!;7B/#iib9&8
 
" = =hG%*		*b188=yyB/yyB/6*0b1ii)4"4	
 		
 ; 9==4:;AACIIK;&%MM*5;BBDKKCPL>#> )HNN,<< 
@[L,>,>,@@ 	  E6immH5;<BBD#GR0668E 7 IMM)4:;AAC126<<> @2B7==?  E  H+-EV 
 $, "4
 	
 9	
 	
 ),ii#6#8@
 *  #}((B7""8,299;W?U?W.0K4K{B/77)*sww7J/K'*+A'B$'(;$<  ww/0;>?W;X !78www,/L ) Y]]95;<BBD%n5 &06vhnM$% %)&8	G &.6vhnM$% &8G *:G&'  ##H-G7$$	14X>
 9==4:;AACIIK8#%MM*5;BBDKKCPLH599Z#<#C#CC#H%y 0EIIiQS<TUH(H"%immJ&?&E2"F"L"L"N"T"T"V-immJ.GHO:: F)IY]]9b-I
28ZH %I(Tg%h*
 4H='H++<[0[vviX6H   yyB/ii%0"4
 	
 *-)+G
 %7G !NO  d  	=!V+ KK < =	=(  	=!V+ KK < =	=(  	=!V+KK < =	=$  	=!V+KK < =	=D  	=!V+KK < =	=sq   j !A6j A!k A,k0 9A!l 8A4m jj$kk$k-,k-0$ll$mm$m.-m.c                N    t        | t              rt        |       S t        |       S rX   )r   r   r   r   )errors    r)   format_runtime_provider_errorr  ;  s!    %# ''u:r+   )r6   )r&   r   r'   r   returnr   )r3   r   r  r   )r=   r   r  r  )rF   r   rG   r   r  r  )rR   r   r  Optional[str])rR   r   r  r   )r  Dict[str, Any]rX   )r   r  r   r  r  r  )r   r  r   r   r  r   )r   r   r  r  )r   r   r   r   r   Optional[Dict[str, Any]]r  r   )r   r   r   r
   r   r   r   r  r   zOptional[CredentialPool]r   r  r  r  )r   r  r  r   )NN)
rR   r   r   r   r   r  r   r  r  r  )r   r  r   r  r  None)r   r   r  r  )r   r   r  r  )rR   r  r  r  r  r  )r  r   )r  r  r  r  )r   r   r  r  r  r  r  r  )r   r   r  r  r  r  r  r  )r   r   r   r  r  r  r  r  r   r  r  r  )r   r   r   r   r   r  r  r  r  r  r  r  )
r   r  r  r  r  r  r   r  r  r  )r  rE   r  r   )Q__doc__
__future__r   loggingr  r   urllib.parser   typingr   r   r   	getLogger__name__r   
hermes_clir   r   agent.credential_poolr	   r
   r   r   agent.secret_scoper   r%   rD   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rT  r   r   hermes_constantsr    utilsr!   r"   r#   r*   r4   r?   rK   rU   rw   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r
  r  r3  rE  r_  r}  r  r   r+   r)   <module>r     s   M "  	 	 ! & &			8	$ ' k k 8    $ K 0 C C
/3=
5<861r.,8""$   (	
 	> +/%)"&FF F 	F
 (F #F  F FR, (,#'	 % !	
 @Zz0j #%)<< #< 	<~8, '+'+	xx $x %	x
 x| '+'+	II $I %	I
 I` '+'+"&ff f $	f
 %f  f f\ '+'+UU U 	U
 $U %U Ut  $&*'+"&LL $L %	L
  L L^r+   