fix(auth): resolve API keys from ~/.hermes/.env and credential_pool

_resolve_api_key_provider_secret() and _seed_from_env() only checked
os.environ for provider API keys. When keys exist in ~/.hermes/.env but
are not loaded into the process environment (e.g. ACP adapter entry
point, post-session-start .env edits, or non-CLI entry points), the
resolution returns an empty string, causing HTTP 401 failures.

Changes:
- credential_pool._seed_from_env: use get_env_value() which checks both
  os.environ and ~/.hermes/.env file, preventing _prune_stale_seeded_entries
  from removing valid entries whose env var isn't in os.environ
- credential_pool._seed_from_env: same fix for openrouter and
  base_url_env_var resolution
- auth._resolve_api_key_provider_secret: use get_env_value() instead of
  os.getenv(), and add credential_pool fallback when env resolution fails

Fixes #15914
This commit is contained in:
阿泥豆
2026-04-26 14:35:55 +08:00
committed by Teknium
parent e3901d5b25
commit 8443998dc3
2 changed files with 37 additions and 4 deletions

View File

@@ -468,10 +468,29 @@ def _resolve_api_key_provider_secret(
return "", ""
for env_var in pconfig.api_key_env_vars:
val = os.getenv(env_var, "").strip()
# Check both os.environ and ~/.hermes/.env file
try:
from hermes_cli.config import get_env_value
val = (get_env_value(env_var) or "").strip()
except Exception:
val = os.getenv(env_var, "").strip()
if has_usable_secret(val):
return val, env_var
# Fallback: try credential pool (e.g. zai key stored via auth.json)
try:
from agent.credential_pool import load_pool
pool = load_pool(provider_id)
if pool and pool.has_credentials():
entry = pool.peek()
if entry:
key = getattr(entry, "access_token", "") or getattr(entry, "runtime_api_key", "")
key = str(key).strip()
if has_usable_secret(key):
return key, f"credential_pool:{provider_id}"
except Exception:
pass
return "", ""