mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-15 09:21:36 +00:00
fix(dashboard): Anthropic API Key entry checks ANTHROPIC_API_KEY, not Claude Code creds; hide deprecated tool-progress env vars (#44286)
Two dashboard fixes: 1. The 'Anthropic API Key' OAuth catalog entry's status fn read ~/.claude/.credentials.json (which has its own dedicated claude-code entry) and never checked ANTHROPIC_API_KEY at all. It now checks the Hermes PKCE file, then the registry env-var order (ANTHROPIC_API_KEY -> ANTHROPIC_TOKEN -> CLAUDE_CODE_OAUTH_TOKEN) via get_env_value, so keys from .env, the shell, or Bitwarden (injected into the process env by load_hermes_dotenv) are all reported, with a '(from Bitwarden)' source suffix when applicable. 2. Deprecated HERMES_TOOL_PROGRESS / HERMES_TOOL_PROGRESS_MODE removed from OPTIONAL_ENV_VARS so the keys page and setup checklists stop offering them. Moved to _EXTRA_ENV_KEYS so .env sanitization and reload_env still recognize them for existing users (gateway back-compat fallback unchanged).
This commit is contained in:
parent
e24c935cf3
commit
9c051f57c3
2 changed files with 46 additions and 42 deletions
|
|
@ -270,6 +270,11 @@ _EXTRA_ENV_KEYS = frozenset({
|
|||
"IRC_SERVER", "IRC_PORT", "IRC_NICKNAME", "IRC_CHANNEL",
|
||||
"IRC_USE_TLS", "IRC_SERVER_PASSWORD", "IRC_NICKSERV_PASSWORD",
|
||||
"TERMINAL_ENV", "TERMINAL_SSH_KEY", "TERMINAL_SSH_PORT",
|
||||
# Deprecated tool-progress env vars — replaced by display.tool_progress in
|
||||
# config.yaml. Kept known here so .env sanitization/reload still handle
|
||||
# them for existing users (gateway reads them as a back-compat fallback),
|
||||
# without surfacing them in user-facing OPTIONAL_ENV_VARS listings.
|
||||
"HERMES_TOOL_PROGRESS", "HERMES_TOOL_PROGRESS_MODE",
|
||||
"WHATSAPP_MODE", "WHATSAPP_ENABLED",
|
||||
"MATTERMOST_HOME_CHANNEL", "MATTERMOST_HOME_CHANNEL_NAME", "MATTERMOST_REPLY_MODE",
|
||||
"MATRIX_PASSWORD", "MATRIX_ENCRYPTION", "MATRIX_DEVICE_ID", "MATRIX_HOME_ROOM",
|
||||
|
|
@ -3557,21 +3562,11 @@ OPTIONAL_ENV_VARS = {
|
|||
},
|
||||
# HERMES_TOOL_PROGRESS and HERMES_TOOL_PROGRESS_MODE are deprecated —
|
||||
# now configured via display.tool_progress in config.yaml (off|new|all|verbose).
|
||||
# Gateway falls back to these env vars for backward compatibility.
|
||||
"HERMES_TOOL_PROGRESS": {
|
||||
"description": "(deprecated) Use display.tool_progress in config.yaml instead",
|
||||
"prompt": "Tool progress (deprecated — use config.yaml)",
|
||||
"url": None,
|
||||
"password": False,
|
||||
"category": "setting",
|
||||
},
|
||||
"HERMES_TOOL_PROGRESS_MODE": {
|
||||
"description": "(deprecated) Use display.tool_progress in config.yaml instead",
|
||||
"prompt": "Progress mode (deprecated — use config.yaml)",
|
||||
"url": None,
|
||||
"password": False,
|
||||
"category": "setting",
|
||||
},
|
||||
# The gateway still falls back to these env vars for backward compatibility,
|
||||
# so they live in _EXTRA_ENV_KEYS (known to .env sanitization/reload) but
|
||||
# are intentionally NOT listed here: OPTIONAL_ENV_VARS feeds user-facing
|
||||
# surfaces (dashboard keys page, setup checklists) and deprecated knobs
|
||||
# shouldn't be offered there.
|
||||
"HERMES_PREFILL_MESSAGES_FILE": {
|
||||
"description": "Path to JSON file with ephemeral prefill messages for few-shot priming",
|
||||
"prompt": "Prefill messages file path",
|
||||
|
|
|
|||
|
|
@ -4468,22 +4468,27 @@ def _truncate_token(value: Optional[str], visible: int = 6) -> str:
|
|||
|
||||
|
||||
def _anthropic_oauth_status() -> Dict[str, Any]:
|
||||
"""Combined status across the three Anthropic credential sources we read.
|
||||
"""Status for the "Anthropic API Key" catalog entry.
|
||||
|
||||
Hermes resolves Anthropic creds in this order at runtime:
|
||||
1. ``~/.hermes/.anthropic_oauth.json`` — Hermes-managed PKCE flow
|
||||
2. ``~/.claude/.credentials.json`` — Claude Code CLI credentials (auto)
|
||||
3. ``ANTHROPIC_TOKEN`` / ``ANTHROPIC_API_KEY`` env vars
|
||||
The dashboard reports the highest-priority source that's actually present.
|
||||
Two sources, in priority order:
|
||||
1. ``~/.hermes/.anthropic_oauth.json`` — Hermes-managed PKCE flow (what
|
||||
this entry's Connect button writes)
|
||||
2. ``ANTHROPIC_API_KEY`` → ``ANTHROPIC_TOKEN`` → ``CLAUDE_CODE_OAUTH_TOKEN``
|
||||
env vars (registry order) — from ``.env``, the shell, or an external
|
||||
secret source like Bitwarden (whose keys are injected into the process
|
||||
env during ``load_hermes_dotenv()``, so the same check covers them)
|
||||
|
||||
Claude Code's ``~/.claude/.credentials.json`` is deliberately NOT read
|
||||
here — it has its own dedicated catalog entry (``claude-code`` →
|
||||
``_claude_code_only_status``). Reporting it under the API-key entry
|
||||
double-counts the token and shadows a real ANTHROPIC_API_KEY.
|
||||
"""
|
||||
try:
|
||||
from agent.anthropic_adapter import (
|
||||
read_hermes_oauth_credentials,
|
||||
read_claude_code_credentials,
|
||||
_HERMES_OAUTH_FILE,
|
||||
)
|
||||
except ImportError:
|
||||
read_claude_code_credentials = None # type: ignore
|
||||
read_hermes_oauth_credentials = None # type: ignore
|
||||
_HERMES_OAUTH_FILE = None # type: ignore
|
||||
|
||||
|
|
@ -4503,29 +4508,33 @@ def _anthropic_oauth_status() -> Dict[str, Any]:
|
|||
"has_refresh_token": bool(hermes_creds.get("refreshToken")),
|
||||
}
|
||||
|
||||
cc_creds = None
|
||||
if read_claude_code_credentials:
|
||||
try:
|
||||
cc_creds = read_claude_code_credentials()
|
||||
except Exception:
|
||||
cc_creds = None
|
||||
if cc_creds and cc_creds.get("accessToken"):
|
||||
return {
|
||||
"logged_in": True,
|
||||
"source": "claude_code",
|
||||
"source_label": "Claude Code (~/.claude/.credentials.json)",
|
||||
"token_preview": _truncate_token(cc_creds.get("accessToken")),
|
||||
"expires_at": cc_creds.get("expiresAt"),
|
||||
"has_refresh_token": bool(cc_creds.get("refreshToken")),
|
||||
}
|
||||
# Env-var / secret-source path. ``get_env_value`` checks the process
|
||||
# environment first (where Bitwarden-sourced secrets land) then .env.
|
||||
env_var_order: tuple = ("ANTHROPIC_API_KEY", "ANTHROPIC_TOKEN", "CLAUDE_CODE_OAUTH_TOKEN")
|
||||
try:
|
||||
from hermes_cli.auth import PROVIDER_REGISTRY
|
||||
env_var_order = PROVIDER_REGISTRY["anthropic"].api_key_env_vars
|
||||
except (ImportError, KeyError):
|
||||
pass
|
||||
try:
|
||||
from hermes_cli.config import get_env_value
|
||||
except ImportError:
|
||||
get_env_value = None # type: ignore
|
||||
try:
|
||||
from hermes_cli.env_loader import format_secret_source_suffix
|
||||
except ImportError:
|
||||
format_secret_source_suffix = None # type: ignore
|
||||
|
||||
env_token = os.getenv("ANTHROPIC_TOKEN") or os.getenv("CLAUDE_CODE_OAUTH_TOKEN")
|
||||
if env_token:
|
||||
for var in env_var_order:
|
||||
value = (get_env_value(var) if get_env_value else None) or os.getenv(var)
|
||||
if not value:
|
||||
continue
|
||||
suffix = format_secret_source_suffix(var) if format_secret_source_suffix else ""
|
||||
return {
|
||||
"logged_in": True,
|
||||
"source": "env_var",
|
||||
"source_label": "ANTHROPIC_TOKEN environment variable",
|
||||
"token_preview": _truncate_token(env_token),
|
||||
"source_label": f"{var}{suffix}",
|
||||
"token_preview": _truncate_token(value),
|
||||
"expires_at": None,
|
||||
"has_refresh_token": False,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue