fix(doctor): use query-param auth for Gemini in API-key probe - #26784
Closed
zhenyu707 wants to merge 1 commit into
Closed
fix(doctor): use query-param auth for Gemini in API-key probe#26784zhenyu707 wants to merge 1 commit into
zhenyu707 wants to merge 1 commit into
Conversation
The shared `_probe_apikey_provider` sends `Authorization: Bearer ${KEY}` to
the provider's `/models` endpoint as a connectivity check. For the gemini
profile this hits `https://generativelanguage.googleapis.com/v1beta/models`,
which is a Google AI Studio surface and only accepts `?key=...` query-param
auth. Sending a Bearer header there returns:
HTTP 401 ACCESS_TOKEN_TYPE_UNSUPPORTED
"Request had invalid authentication credentials. Expected OAuth 2 access
token, login cookie or other valid authentication credential."
The probe's generic 401 branch then reports `✗ gemini (invalid API key)`
for every user with a perfectly working `GEMINI_API_KEY` — `hermes` itself
calls Gemini via `GeminiNativeClient`, which uses the correct auth scheme.
Only the doctor probe is wrong.
Fix: detect the `generativelanguage.googleapis.com` host on the resolved
URL and switch to query-param auth (`?key=…`) before the request, dropping
the `Authorization` header so Google's API gateway accepts it.
Verified with a real `GEMINI_API_KEY`:
- Before: `✗ gemini (invalid API key)`
- After: `✓ gemini`
Both `generateContent` and `listModels` return 200 against the same key
when sent with query-param auth, confirming the credential was always
valid.
Author
|
Closing — withdrawing this PR; will keep the fix as a local patch for now. No action needed from maintainers. |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
hermes doctorfalsely reports✗ gemini (invalid API key)for every user with a workingGEMINI_API_KEY. Root cause: the generic_probe_apikey_providerinhermes_cli/doctor.py:1412–1490sendsAuthorization: Bearer ${KEY}to/models, but the gemini profile'sbase_url=https://generativelanguage.googleapis.com/v1betaonly accepts?key=…query-param auth. Google's API gateway returns:…which the generic 401 branch reports as
(invalid API key). The credential is fine —hermesitself usesGeminiNativeClientwhich sends auth correctly. Only the doctor probe is wrong.Fix
Detect
generativelanguage.googleapis.comon the resolved URL (via the existingbase_url_host_matcheshelper, same pattern used forapi.kimi.comtwo lines up). When matched, rewrite the URL with?key=…and drop theAuthorizationheader so Google's gateway accepts the request.10 lines, additive only — no change to behavior for any other provider.
Verification
Reproduced and verified against a real
GEMINI_API_KEY:Test plan
python -c "import ast; ast.parse(open('hermes_cli/doctor.py').read())"— syntax OKPYTHONPATH=. python -m hermes_cli.main doctorflipsgeminifrom✗to✓against a real keygenerativelanguage.googleapis.comhosttests/hermes_cli/test_doctor.pyandtest_doctor_dedicated_provider_skip.pypass (please run in CI)