Skip to content

fix(providers): honour config.yaml api_key for anthropic provider - #7581

Open
FrankSen wants to merge 1 commit into
NousResearch:mainfrom
FrankSen:fix/anthropic-config-api-key
Open

fix(providers): honour config.yaml api_key for anthropic provider#7581
FrankSen wants to merge 1 commit into
NousResearch:mainfrom
FrankSen:fix/anthropic-config-api-key

Conversation

@FrankSen

Copy link
Copy Markdown

Summary

Fixes #7579

  • Add model.api_key / model.api from config.yaml as a candidate source for the anthropic provider, consistent with how all other providers (openrouter, custom, minimax, etc.) handle it
  • Apply the fix in both the main resolution path (resolve_runtime_provider) and the explicit override path (_resolve_explicit_runtime)
  • Add 2 new tests verifying config api_key and api field resolution

Priority order after fix

  1. Explicit API key (CLI --api-key flag)
  2. config.yaml model.api_key / model.api
  3. ANTHROPIC_TOKEN env var
  4. CLAUDE_CODE_OAUTH_TOKEN env var
  5. Claude Code credential files
  6. ANTHROPIC_API_KEY env var

Test plan

  • All 62 existing + new tests pass (pytest tests/hermes_cli/test_runtime_provider_resolution.py)
  • Manually verified: hermes chat works with only config.yaml api_key set (no env vars)
  • Existing anthropic env var resolution still works when config api_key is absent

The anthropic provider code path in `resolve_runtime_provider()` only
checked env vars (ANTHROPIC_TOKEN, ANTHROPIC_API_KEY) and credential
files for API key resolution, completely ignoring `model.api_key` from
config.yaml. This is inconsistent with all other providers (openrouter,
custom, minimax, etc.) which read config.yaml api_key as a candidate.

Users who configure `provider: anthropic` with `api_key` in config.yaml
(e.g. pointing to a self-hosted proxy) were forced to duplicate the key
in env vars, which is confusing and unnecessary.

This change adds config.yaml `model.api_key` (and `model.api` alias) as
a candidate source in both the main anthropic resolution path and the
explicit override path, consistent with how other providers handle it.

Priority order is now:
  1. Explicit API key (CLI flag)
  2. config.yaml model.api_key / model.api
  3. ANTHROPIC_TOKEN env var
  4. CLAUDE_CODE_OAUTH_TOKEN env var
  5. Claude Code credential files
  6. ANTHROPIC_API_KEY env var

Co-Authored-By: Franksen <youngsenman@163.com>
@FrankSen

Copy link
Copy Markdown
Author

Friendly ping — any feedback on this fix? Happy to adjust if needed.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/cli CLI entry point, hermes_cli/, setup wizard provider/anthropic Anthropic native Messages API area/config Config system, migrations, profiles labels Apr 29, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #9105 (same root cause: anthropic provider path in resolve_runtime_provider() skips config.yaml api_key). Also related to closed #11713.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for identifying the missing Anthropic configuration path. The underlying non-Azure gap still exists on current main: hermes_cli/runtime_provider.py:1901-1908 calls resolve_anthropic_token() without considering model.api_key.

Problems

  • The resolver was substantially refactored after this PR. The current explicit path is hermes_cli/runtime_provider.py:1367-1392 and the normal native path is :1849-1916, so this patch needs a focused port rather than a direct cherry-pick.
  • The new tests cover only the normal resolver. They do not exercise the explicit branch changed by the PR, which is entered only with an explicit runtime argument (hermes_cli/runtime_provider.py:1362-1365, :1658-1666).
  • Current configuration/docs define model.api_key as custom-endpoint-only (hermes_cli/config.py:4555-4559; website/docs/user-guide/features/credential-pools.md:188). Extending it to native Anthropic needs that contract reconciled.

Suggested changes

  • Port both branches and add one explicit-base-url regression with only model.api_key configured.
  • Update the configuration/docs contract if native Anthropic inline keys are intentional.

Automated hermes-sweeper review.

assert resolved.get("credential_pool") is None


def test_resolve_runtime_provider_anthropic_respects_config_api_key(monkeypatch):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This covers the normal resolver only. Please add a regression for the _resolve_explicit_runtime path as well: pass explicit_base_url with no explicit_api_key, provide model.api_key, and assert it wins without calling resolve_anthropic_token.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit labels Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists provider/anthropic Anthropic native Messages API sweeper:blast-broad Sweeper blast radius: broad — a core path most sessions hit sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Anthropic provider ignores config.yaml api_key, requiring duplicate env var configuration

3 participants