102 lines
5.1 KiB
Markdown
102 lines
5.1 KiB
Markdown
---
|
|
summary: "Gemini provider data sources: OAuth-backed quota APIs, token refresh, and tier detection."
|
|
read_when:
|
|
- Debugging Gemini quota fetch or auth issues
|
|
- Updating Gemini CLI OAuth integration
|
|
- Adjusting tier detection or model mapping
|
|
---
|
|
|
|
# Gemini provider
|
|
|
|
Gemini uses the Gemini CLI OAuth credentials and private quota APIs. No browser cookies.
|
|
|
|
## Data sources + fallback order
|
|
|
|
1) **OAuth-backed quota API** (only path used in `fetch()`)
|
|
- Reads auth type from `~/.gemini/settings.json`.
|
|
- Supported: `oauth-personal` (or unknown → try OAuth creds).
|
|
- Unsupported: `api-key`, `vertex-ai` (hard error).
|
|
|
|
2) **Legacy CLI parsing** (parser exists but not used in current fetch path)
|
|
- `GeminiStatusProbe.parse(text:)` can parse `/stats` output.
|
|
|
|
## OAuth credentials
|
|
- File: `~/.gemini/oauth_creds.json`.
|
|
- Required fields: `access_token`, `refresh_token` (optional), `id_token`, `expiry_date`.
|
|
- If access token is expired, we refresh via Google OAuth using client ID/secret extracted
|
|
from the Gemini CLI install (see below).
|
|
|
|
## OAuth client ID/secret extraction
|
|
- Resolution order:
|
|
1. `GEMINI_OAUTH_CLIENT_ID` + `GEMINI_OAUTH_CLIENT_SECRET` environment override.
|
|
2. `GEMINI_OAUTH2_JS_PATH` pointing at a readable `oauth2.js` file.
|
|
3. Installed Gemini CLI package (`oauth2.js` / bundle regex extraction).
|
|
4. Known global Gemini CLI install paths (Homebrew npm prefix layouts, then
|
|
Homebrew Cellar/`opt` `libexec` package roots when the GUI cannot resolve
|
|
the `gemini` binary).
|
|
- We locate the installed `gemini` binary, then search for:
|
|
- Homebrew nested path:
|
|
- `.../libexec/lib/node_modules/@google/gemini-cli/node_modules/@google/gemini-cli-core/dist/src/code_assist/oauth2.js`
|
|
- Homebrew Cellar/opt package root (no-binary fallback):
|
|
- `/opt/homebrew/Cellar/gemini-cli/<version>/libexec/lib/node_modules/@google/gemini-cli`
|
|
- `/opt/homebrew/opt/gemini-cli/libexec/lib/node_modules/@google/gemini-cli`
|
|
- same under `/usr/local`
|
|
- Bun/npm sibling path:
|
|
- `.../node_modules/@google/gemini-cli-core/dist/src/code_assist/oauth2.js`
|
|
- Regex extraction:
|
|
- `OAUTH_CLIENT_ID` and `OAUTH_CLIENT_SECRET` from `oauth2.js` or Homebrew bundle chunks.
|
|
|
|
## API endpoints
|
|
- Quota:
|
|
- `POST https://cloudcode-pa.googleapis.com/v1internal:retrieveUserQuota`
|
|
- Body: `{ "project": "<projectId>" }` (or `{}` if unknown)
|
|
- Header: `Authorization: Bearer <access_token>`
|
|
- Project discovery (quota project ID):
|
|
- Primary: `cloudaicompanionProject` from `loadCodeAssist`.
|
|
- Fallback: `GET https://cloudresourcemanager.googleapis.com/v1/projects`
|
|
- Picks `gen-lang-client*` or label `generative-language`.
|
|
- Tier detection:
|
|
- `POST https://cloudcode-pa.googleapis.com/v1internal:loadCodeAssist`
|
|
- Body: `{ "metadata": { "ideType": "GEMINI_CLI", "pluginType": "GEMINI" } }`
|
|
- Token refresh:
|
|
- `POST https://oauth2.googleapis.com/token`
|
|
- Form body: `client_id`, `client_secret`, `refresh_token`, `grant_type=refresh_token`.
|
|
|
|
## Parsing + mapping
|
|
- Quota buckets:
|
|
- `remainingFraction`, `resetTime`, `modelId`.
|
|
- For each model, lowest `remainingFraction` wins.
|
|
- `percentLeft = remainingFraction * 100`.
|
|
- Reset:
|
|
- `resetTime` parsed as ISO-8601, formatted as "Resets in Xh Ym".
|
|
- UI mapping:
|
|
- Primary: Pro models (lowest percent left).
|
|
- Secondary: Flash models (lowest percent left).
|
|
|
|
## Plan detection
|
|
- Tier from `loadCodeAssist`:
|
|
- `paidTier.name` → paid subscription label from Google, preferred whenever present
|
|
- `standard-tier` → "Paid" (fallback when `paidTier.name` is absent)
|
|
- `free-tier` + `hd` claim → "Workspace" (fallback when `paidTier.name` is absent)
|
|
- `free-tier` → "Free"
|
|
- `legacy-tier` → "Legacy"
|
|
- Email from `id_token` JWT claims.
|
|
|
|
## Consumer-tier migration (June 2026)
|
|
- [Google stopped serving](https://developers.google.com/gemini-code-assist/docs/deprecations/code-assist-individuals)
|
|
Gemini CLI OAuth for individual, AI Pro, and Ultra accounts on 2026-06-18. Standard and Enterprise
|
|
subscriptions remain supported; paid API-key access is outside CodexBar's OAuth-backed Gemini provider.
|
|
- When quota, `loadCodeAssist`, or token-refresh responses include Google's unsupported-client
|
|
migration signal (`UNSUPPORTED_CLIENT`, `IneligibleTierError`, or Antigravity migration copy),
|
|
CodexBar surfaces `consumerTierDeprecated` with guidance to use the Antigravity provider.
|
|
- Settings shows an **Enable Antigravity provider** action only after CodexBar observes
|
|
`consumerTierDeprecated` during a Gemini refresh (typed sentinel state, not user-facing text matching).
|
|
- The action is explicit: CodexBar never automatically enables Antigravity or falls back to it.
|
|
- Ordinary Gemini login, `notLoggedIn`, and Antigravity setup errors remain unchanged. CodexBar does not
|
|
capture Terminal `gemini` OAuth output, so Terminal-only failures cannot activate the migration action.
|
|
- Workspace and education Google accounts are outside the June 2026 consumer shutdown; keep using the
|
|
Gemini provider. Antigravity remains the consumer replacement path for individual, AI Pro, and Ultra.
|
|
|
|
## Key files
|
|
- `Sources/CodexBarCore/Providers/Gemini/GeminiStatusProbe.swift`
|