Skip to content

fix(models): use Anthropic-native headers for model validation#12618

Closed
H-Ali13381 wants to merge 2 commits into
NousResearch:mainfrom
H-Ali13381:fix/anthropic-model-validation-auth
Closed

fix(models): use Anthropic-native headers for model validation#12618
H-Ali13381 wants to merge 2 commits into
NousResearch:mainfrom
H-Ali13381:fix/anthropic-model-validation-auth

Conversation

@H-Ali13381

Copy link
Copy Markdown
Contributor

Problem

When switching models with the Anthropic provider, /model <name> always fails with a misleading "service unreachable" error — even with a valid API key.

Root cause: validate_requested_model() falls through to a generic OpenAI-compatible /v1/models probe that sends Authorization: Bearer <key>. Anthropic's API requires x-api-key + anthropic-version headers (or Authorization: Bearer only for OAuth tokens from Claude Code), so every probe returns 401 Unauthorized, which the validation code interprets as the service being down.

Fix

Add a dedicated normalized == "anthropic" early-return branch that calls the existing _fetch_anthropic_models() helper, which already handles both regular API keys and Claude Code OAuth tokens correctly. This mirrors the existing pattern for openai-codex, copilot, and bedrock.

The branch also adds:

  • Fuzzy auto-correct (cutoff 0.9) — catches near-exact typos (e.g. claude-sonnet-4claude-sonnet-4-5)
  • Fuzzy suggestions (cutoff 0.5) — surfaces similar model IDs when the requested one is not listed
  • Graceful fallback — if the token cannot be resolved or the network is down, accepts with a warning rather than hard-failing, since newer/preview/snapshot model IDs are sometimes not listed on /v1/models yet

How to reproduce (before fix)

# With ANTHROPIC_API_KEY set to a valid key:
/model claude-sonnet-4-6 --provider anthropic
# → "Anthropic service unreachable" (every probe 401s with wrong headers)

After fix

/model claude-sonnet-4-6 --provider anthropic
# → Validates correctly via x-api-key + anthropic-version headers
# → Auto-corrects typos, suggests similar model IDs on mismatch
# → Falls through gracefully if network is unavailable

Files changed

  • hermes_cli/models.py — 43-line insertion; no other files touched

H-Ali13381 and others added 2 commits April 19, 2026 12:34
The generic /v1/models probe in validate_requested_model() sent a plain
'Authorization: Bearer <key>' header, which works for OpenAI-compatible
endpoints but results in a 401 Unauthorized from Anthropic's API.
Anthropic requires x-api-key + anthropic-version headers (or Bearer for
OAuth tokens from Claude Code).

Add a provider-specific branch for normalized == 'anthropic' that calls
the existing _fetch_anthropic_models() helper, which already handles
both regular API keys and Claude Code OAuth tokens correctly.  This
mirrors the pattern already used for openai-codex, copilot, and bedrock.

The branch also includes:
- fuzzy auto-correct (cutoff 0.9) for near-exact model ID typos
- fuzzy suggestions (cutoff 0.5) when the model is not listed
- graceful fall-through when the token cannot be resolved or the
  network is unreachable (accepts with a warning rather than hard-fail)
- a note that newer/preview/snapshot model IDs can be gate-listed
  and may still work even if not returned by /v1/models

Fixes Anthropic provider users seeing 'service unreachable' errors
when running /model <claude-model> because every probe 401'd.
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/cli CLI entry point, hermes_cli/, setup wizard provider/anthropic Anthropic native Messages API labels Apr 23, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Competes with #13189 and #12950 — all three fix Anthropic model validation using wrong auth headers. Review needed to pick one.

teknium1 pushed a commit that referenced this pull request Apr 24, 2026
Salvage of the Gemini-specific piece from PR #12585 by @briandevans.
Gemini's OpenAI-compat /v1beta/openai/models endpoint returns IDs prefixed
with 'models/' (native Gemini-API convention), so set-membership against
curated bare IDs drops every model. Strip the prefix before comparison.

The Anthropic static-catalog piece of #12585 was subsumed by #12618's
_fetch_anthropic_models() branch landing earlier in the same salvage PR.
Full branch cherry-pick was skipped because it also carried unrelated
catalog-version regressions.
justrhoto pushed a commit to justrhoto/hermes-agent that referenced this pull request Apr 24, 2026
…2532)

Salvage of the Gemini-specific piece from PR NousResearch#12585 by @briandevans.
Gemini's OpenAI-compat /v1beta/openai/models endpoint returns IDs prefixed
with 'models/' (native Gemini-API convention), so set-membership against
curated bare IDs drops every model. Strip the prefix before comparison.

The Anthropic static-catalog piece of NousResearch#12585 was subsumed by NousResearch#12618's
_fetch_anthropic_models() branch landing earlier in the same salvage PR.
Full branch cherry-pick was skipped because it also carried unrelated
catalog-version regressions.
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for this fix, @H-Ali13381! The change has already landed on main — this was an automated hermes-sweeper review.

Evidence:

  • Commit 2303dd8 on main implements the exact fix from this PR: the normalized == "anthropic" branch in validate_requested_model() dispatching to _fetch_anthropic_models() with x-api-key + anthropic-version headers, fuzzy auto-correct (cutoff 0.9), fuzzy suggestions (cutoff 0.5), and graceful fallback.
  • The implementation lives at hermes_cli/models.py lines 2733–2785.
  • The fix landed after the v2026.4.23 release tag and will ship in the next weekly release.

Closing as implemented on main.

@teknium1 teknium1 closed this Apr 27, 2026
ulasbilgen pushed a commit to ulasbilgen/hermes-adhd-agent that referenced this pull request May 1, 2026
…2532)

Salvage of the Gemini-specific piece from PR NousResearch#12585 by @briandevans.
Gemini's OpenAI-compat /v1beta/openai/models endpoint returns IDs prefixed
with 'models/' (native Gemini-API convention), so set-membership against
curated bare IDs drops every model. Strip the prefix before comparison.

The Anthropic static-catalog piece of NousResearch#12585 was subsumed by NousResearch#12618's
_fetch_anthropic_models() branch landing earlier in the same salvage PR.
Full branch cherry-pick was skipped because it also carried unrelated
catalog-version regressions.
aj-nt pushed a commit to aj-nt/hermes-agent that referenced this pull request May 1, 2026
…2532)

Salvage of the Gemini-specific piece from PR NousResearch#12585 by @briandevans.
Gemini's OpenAI-compat /v1beta/openai/models endpoint returns IDs prefixed
with 'models/' (native Gemini-API convention), so set-membership against
curated bare IDs drops every model. Strip the prefix before comparison.

The Anthropic static-catalog piece of NousResearch#12585 was subsumed by NousResearch#12618's
_fetch_anthropic_models() branch landing earlier in the same salvage PR.
Full branch cherry-pick was skipped because it also carried unrelated
catalog-version regressions.
donald131 pushed a commit to donald131/hermes-agent that referenced this pull request May 2, 2026
…2532)

Salvage of the Gemini-specific piece from PR NousResearch#12585 by @briandevans.
Gemini's OpenAI-compat /v1beta/openai/models endpoint returns IDs prefixed
with 'models/' (native Gemini-API convention), so set-membership against
curated bare IDs drops every model. Strip the prefix before comparison.

The Anthropic static-catalog piece of NousResearch#12585 was subsumed by NousResearch#12618's
_fetch_anthropic_models() branch landing earlier in the same salvage PR.
Full branch cherry-pick was skipped because it also carried unrelated
catalog-version regressions.
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
…2532)

Salvage of the Gemini-specific piece from PR NousResearch#12585 by @briandevans.
Gemini's OpenAI-compat /v1beta/openai/models endpoint returns IDs prefixed
with 'models/' (native Gemini-API convention), so set-membership against
curated bare IDs drops every model. Strip the prefix before comparison.

The Anthropic static-catalog piece of NousResearch#12585 was subsumed by NousResearch#12618's
_fetch_anthropic_models() branch landing earlier in the same salvage PR.
Full branch cherry-pick was skipped because it also carried unrelated
catalog-version regressions.
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…2532)

Salvage of the Gemini-specific piece from PR NousResearch#12585 by @briandevans.
Gemini's OpenAI-compat /v1beta/openai/models endpoint returns IDs prefixed
with 'models/' (native Gemini-API convention), so set-membership against
curated bare IDs drops every model. Strip the prefix before comparison.

The Anthropic static-catalog piece of NousResearch#12585 was subsumed by NousResearch#12618's
_fetch_anthropic_models() branch landing earlier in the same salvage PR.
Full branch cherry-pick was skipped because it also carried unrelated
catalog-version regressions.
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
…2532)

Salvage of the Gemini-specific piece from PR NousResearch#12585 by @briandevans.
Gemini's OpenAI-compat /v1beta/openai/models endpoint returns IDs prefixed
with 'models/' (native Gemini-API convention), so set-membership against
curated bare IDs drops every model. Strip the prefix before comparison.

The Anthropic static-catalog piece of NousResearch#12585 was subsumed by NousResearch#12618's
_fetch_anthropic_models() branch landing earlier in the same salvage PR.
Full branch cherry-pick was skipped because it also carried unrelated
catalog-version regressions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P1 High — major feature broken, no workaround provider/anthropic Anthropic native Messages API type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants