Skip to content

feat(xai): Grok via grok.com subscription or API key#112

Merged
davidrhodus merged 1 commit into
mainfrom
feat/xai-grok-subscription-login
Jul 19, 2026
Merged

feat(xai): Grok via grok.com subscription or API key#112
davidrhodus merged 1 commit into
mainfrom
feat/xai-grok-subscription-login

Conversation

@davidrhodus

Copy link
Copy Markdown
Contributor

Adds xAI as a provider, with two ways to authenticate: a metered XAI_API_KEY from console.x.ai, or a grok.com subscription (SuperGrok / X Premium) via OAuth device-code login — the same shape as signing into Claude Code with a Pro/Max account instead of an API key.

/login xai device code -> browser approval -> stored credential
/provider picker; profiles first, then provider presets
hi --provider xai

Endpoint: both credential types go to https://api.x.ai/v1 as an ordinary bearer. xAI's own CLI routes subscription traffic to cli-chat-proxy.grok.com instead, but that host is gated on a Grok CLI version claim and serves a strictly smaller catalogue (grok-4.5 only, vs ten models on api.x.ai), so there is nothing to gain by imitating it. Verified against a live SuperGrokPro account.

Notable pieces:

  • TokenSource (hi-ai/src/token.rs) — providers re-read the credential per request instead of capturing a String at construction, so an OAuth token that expires mid-session can be re-minted. StaticToken covers API keys and never refreshes, so a wrong key still fails fast.
  • auth.json (hi-ai/src/auth_store.rs) — ~/.config/hi/auth.json, written via a 0600 temp file and renamed, so a secret is never briefly world-readable and readers never see a partial file. Deliberately not config.toml, whose layering includes a project-local ./hi.toml that could be committed.
  • Refresh preserves an unrotated refresh token: xAI omits refresh_token when it does not rotate, and requiring the field logs the user out at the first expiry.
  • Auth-failure detection now reads the body, not just the status: xAI answers a bad credential with HTTP 400 invalid-argument, which previously fell through to the request-shape branch and made the compat ladder retry a request that could never succeed.
  • /provider accepts a bare provider name, so /provider xai works straight after /login xai with no profile to set up first. Profiles still shadow presets. Selecting a model on a preset no longer errors about a missing profile.
  • Provider form: up/down now pick the provider and left/right move the cursor (previously left only worked on one field, right hijacked every field, and up/down did nothing).

Also carries an unrelated in-flight change to sync.rs/main.rs from the repo's autonomous loop (RemoteSessionSink::set_accepts_input), which was interleaved in the working tree and is required for this to build.

Adds xAI as a provider, with two ways to authenticate: a metered
XAI_API_KEY from console.x.ai, or a grok.com subscription (SuperGrok /
X Premium) via OAuth device-code login — the same shape as signing into
Claude Code with a Pro/Max account instead of an API key.

  /login xai      device code -> browser approval -> stored credential
  /provider       picker; profiles first, then provider presets
  hi --provider xai

Endpoint: both credential types go to https://api.x.ai/v1 as an ordinary
bearer. xAI's own CLI routes subscription traffic to cli-chat-proxy.grok.com
instead, but that host is gated on a Grok CLI version claim and serves a
strictly smaller catalogue (grok-4.5 only, vs ten models on api.x.ai), so
there is nothing to gain by imitating it. Verified against a live
SuperGrokPro account.

Notable pieces:

- TokenSource (hi-ai/src/token.rs) — providers re-read the credential per
  request instead of capturing a String at construction, so an OAuth token
  that expires mid-session can be re-minted. StaticToken covers API keys and
  never refreshes, so a wrong key still fails fast.
- auth.json (hi-ai/src/auth_store.rs) — ~/.config/hi/auth.json, written via
  a 0600 temp file and renamed, so a secret is never briefly world-readable
  and readers never see a partial file. Deliberately not config.toml, whose
  layering includes a project-local ./hi.toml that could be committed.
- Refresh preserves an unrotated refresh token: xAI omits refresh_token when
  it does not rotate, and requiring the field logs the user out at the first
  expiry.
- Auth-failure detection now reads the body, not just the status: xAI answers
  a bad credential with HTTP 400 invalid-argument, which previously fell
  through to the request-shape branch and made the compat ladder retry a
  request that could never succeed.
- /provider accepts a bare provider name, so `/provider xai` works straight
  after `/login xai` with no profile to set up first. Profiles still shadow
  presets. Selecting a model on a preset no longer errors about a missing
  profile.
- Provider form: up/down now pick the provider and left/right move the cursor
  (previously left only worked on one field, right hijacked every field, and
  up/down did nothing).

Also carries an unrelated in-flight change to sync.rs/main.rs from the
repo's autonomous loop (RemoteSessionSink::set_accepts_input), which was
interleaved in the working tree and is required for this to build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@davidrhodus
davidrhodus merged commit 2eb1ec5 into main Jul 19, 2026
1 check failed
@davidrhodus
davidrhodus deleted the feat/xai-grok-subscription-login branch July 19, 2026 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant