Files
hermes-agent/website
Teknium 1e5ee33f68 feat(gemini): add Google Gemini (OAuth) inference provider
Adds 'google-gemini-cli' as a first-class inference provider using
Authorization Code + PKCE (S256) OAuth against Google's accounts.google.com,
hitting the OpenAI-compatible Gemini endpoint (v1beta/openai) with a Bearer
access token. Users sign in with their Google account — no API-key copy-paste.

Synthesized from three competing PRs per multi-PR design analysis:
- Clean PKCE module structure shaped after #10176 (thanks @sliverp)
- Cross-process file lock (fcntl POSIX / msvcrt Windows) with thread-local
  re-entrancy counter from #10779 (thanks @newarthur)
- Rejects #6745's subprocess approach entirely (different paradigm)

Improvements over the competing PRs:
- Port fallback: if 8085 is taken, bind ephemeral port instead of failing
- Preserves refresh_token when Google omits one (correct per Google spec)
- Accepts both full redirect URL and bare code in paste fallback
- doctor.py health check (neither PR had this)
- No regression in _OAUTH_CAPABLE_PROVIDERS (#10779 dropped anthropic/nous)
- No bundled unrelated features (#10779 mixed in persona/personality routing)

Storage:
- ~/.hermes/auth/google_oauth.json (0o600, atomic write via fsync+replace)
- Cross-process fcntl/msvcrt lock with 30s timeout
- Refresh 5 min before expiry on every request via get_valid_access_token

Provider registration (9-point checklist):
- auth.py: PROVIDER_REGISTRY entry, aliases (gemini-cli, gemini-oauth),
  resolve_gemini_oauth_runtime_credentials, get_gemini_oauth_auth_status,
  get_auth_status() dispatch
- models.py: _PROVIDER_MODELS catalog, CANONICAL_PROVIDERS entry, aliases
- providers.py: HermesOverlay, ALIASES entries
- runtime_provider.py: resolve_runtime_provider() dispatch branch
- config.py: OPTIONAL_ENV_VARS for HERMES_GEMINI_CLIENT_ID/_SECRET/_BASE_URL
- main.py: _model_flow_google_gemini_cli, select_provider_and_model dispatch
- auth_commands.py: add-to-pool handler, _OAUTH_CAPABLE_PROVIDERS
- doctor.py: 'Google Gemini OAuth' status line

Client ID: Not shipped. Users register a Desktop OAuth client in Google Cloud
Console (Generative Language API) and set HERMES_GEMINI_CLIENT_ID in
~/.hermes/.env. Documented in website/docs/integrations/providers.md.

Tests: 44 new unit tests covering PKCE S256 roundtrip, credential I/O
(permissions + atomic write), cross-process lock, port fallback, paste
fallback (URL + bare code), token exchange/refresh, rotation handling,
get_valid_access_token refresh semantics, runtime provider dispatch,
alias resolution, and regression guards for _OAUTH_CAPABLE_PROVIDERS.

Docs: new 'Google Gemini via OAuth' section in providers.md with full
walkthrough including GCP Desktop OAuth client registration, and env var
table updated in environment-variables.md.

Closes partial work in #6745, #10176, #10779 (to be closed with credit
once this merges).
2026-04-16 15:08:49 -07:00
..
2026-03-14 22:49:57 -07:00
2026-03-14 22:49:57 -07:00

Website

This website is built using Docusaurus, a modern static website generator.

Installation

yarn

Local Development

yarn start

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

Build

yarn build

This command generates static content into the build directory and can be served using any static contents hosting service.

Deployment

Using SSH:

USE_SSH=true yarn deploy

Not using SSH:

GIT_USER=<Your GitHub username> yarn deploy

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the gh-pages branch.

Diagram Linting

CI runs ascii-guard to lint docs for ASCII box diagrams. Use Mermaid (````mermaid`) or plain lists/tables instead of ASCII boxes to avoid CI failures.