You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixes the dashboard's "Anthropic API Key" row launching a Claude subscription OAuth sign-in (#91822): the row's Login button opens Hermes' claude.ai OAuth (pkce) with no key field in sight, so users who never selected a Claude model got an unexpected Claude sign-in page from a row labeled as the API-key path.
Root cause is the catalog entry's NAME, not its flow: _OAUTH_PROVIDER_CATALOG's anthropic entry is named "Anthropic API Key" while "flow": "pkce" — and that flow is load-bearing (existing PKCE users' status reporting and the disconnect path that clears ~/.hermes/.anthropic_oauth.json both key off it; switching the row to flow: "external" to hide the button would strand those users). This is the label-side sibling of #24058's dispatch fix: the dispatcher routes pkce correctly now, but the label still promised the wrong thing.
The fix renames the entry to "Anthropic OAuth (Claude Sign-in)" so the button's name matches its behavior; the API-key path remains the row's documented cli_command (hermes auth add anthropic). It also fixes an independent hint-ordering bug surfaced on the way: _oauth_provider_disconnect_hint now checks source == "env_var" before the flow == "external" early return, so an env-sourced key always gets the "Remove the API key from Settings → Keys instead." hint regardless of the row's flow.
🐛 Bug fix (non-breaking change that fixes an issue)
Changes Made
hermes_cli/web_server.py — _OAUTH_PROVIDER_CATALOG: renamed the anthropic entry from "Anthropic API Key" to "Anthropic OAuth (Claude Sign-in)" with a comment explaining why the name must match the pkce button and where the real key path lives; _oauth_provider_disconnect_hint: moved the env_var check ahead of the external early return (an env-sourced key's removal hint is flow-independent).
tests/hermes_cli/test_web_oauth_dispatch.py — test_anthropic_row_name_matches_its_oauth_behavior: pins that the row's name contains no "API Key" claim and names OAuth, and that the flow stays pkce (existing users' paths depend on it).
How to Test
Automated: .venv/bin/python -m pytest tests/hermes_cli/test_web_oauth_dispatch.py tests/hermes_cli/test_anthropic_oauth_flow.py tests/hermes_cli/test_dashboard_oauth_endpoints_server_gate.py -q — should pass (observed result: 20 passed on macOS arm64).
Manual: open the dashboard's Keys/Accounts card — the Anthropic row now reads "Anthropic OAuth (Claude Sign-in)"; its Login behavior is unchanged (Claude sign-in), and the API-key instructions still point at hermes auth add anthropic.
AI code review — automated review for reference; please use your judgment.
Right-sized fix with the regression test written the way it should be: pins the label contract ("OAuth" present, "API Key" absent) and asserts flow stays pkce so nobody "completes" this by breaking dispatch.
hermes_cli/web_server.py (_oauth_provider_disconnect_hint) — The reorder makes env_var win over external-flow for ALL providers, not just the anthropic row. A credential that is genuinely managed by a provider CLI (external flow, disconnect command available) but happens to also have an env var set will now be told "remove it from Settings → Keys", which doesn't actually detach the CLI-stored credential — and removing the env var may not even stop Hermes from using the stored one. Suggestion: either scope the new precedence to rows where Hermes stores the key itself (the Dashboard row "Anthropic API Key" launches Claude OAuth instead of API-key setup #91822 case), or document why env-var sourcing always outranks external management.
Testing — The rename is tested but the hint reorder is not; add one case per combination (env_var+external, env_var+pkce, external-without-env) so the intended precedence table is executable rather than implicit in ordering.
Nit: the row's docs_url still points to Anthropic's generic API getting-started page while the row now advertises OAuth sign-in; pointing it at the Claude OAuth/connection doc would finish the labeling job.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
area/authAuthentication, OAuth, credential poolscomp/cliCLI entry point, hermes_cli/, setup wizardcomp/dashboardWeb dashboard / control panel UI (dashboard/, landing)P2Medium — degraded but workaround existsprovider/anthropicAnthropic native Messages APItype/bugSomething isn't working
3 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes the dashboard's "Anthropic API Key" row launching a Claude subscription OAuth sign-in (#91822): the row's Login button opens Hermes' claude.ai OAuth (pkce) with no key field in sight, so users who never selected a Claude model got an unexpected Claude sign-in page from a row labeled as the API-key path.
Root cause is the catalog entry's NAME, not its flow:
_OAUTH_PROVIDER_CATALOG'santhropicentry is named "Anthropic API Key" while"flow": "pkce"— and that flow is load-bearing (existing PKCE users' status reporting and the disconnect path that clears~/.hermes/.anthropic_oauth.jsonboth key off it; switching the row toflow: "external"to hide the button would strand those users). This is the label-side sibling of #24058's dispatch fix: the dispatcher routes pkce correctly now, but the label still promised the wrong thing.The fix renames the entry to "Anthropic OAuth (Claude Sign-in)" so the button's name matches its behavior; the API-key path remains the row's documented
cli_command(hermes auth add anthropic). It also fixes an independent hint-ordering bug surfaced on the way:_oauth_provider_disconnect_hintnow checkssource == "env_var"before theflow == "external"early return, so an env-sourced key always gets the "Remove the API key from Settings → Keys instead." hint regardless of the row's flow.Related Issue
Fixes #91822
Type of Change
Changes Made
hermes_cli/web_server.py—_OAUTH_PROVIDER_CATALOG: renamed theanthropicentry from "Anthropic API Key" to "Anthropic OAuth (Claude Sign-in)" with a comment explaining why the name must match the pkce button and where the real key path lives;_oauth_provider_disconnect_hint: moved theenv_varcheck ahead of theexternalearly return (an env-sourced key's removal hint is flow-independent).tests/hermes_cli/test_web_oauth_dispatch.py—test_anthropic_row_name_matches_its_oauth_behavior: pins that the row's name contains no "API Key" claim and names OAuth, and that the flow stays pkce (existing users' paths depend on it).How to Test
.venv/bin/python -m pytest tests/hermes_cli/test_web_oauth_dispatch.py tests/hermes_cli/test_anthropic_oauth_flow.py tests/hermes_cli/test_dashboard_oauth_endpoints_server_gate.py -q— should pass (observed result: 20 passed on macOS arm64).hermes auth add anthropic.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass (targeted OAuth/dashboard suites: 20 passed, 0 failures)Documentation & Housekeeping
docs/, docstrings) — or N/A (catalog comment documents the naming rationale)cli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/A