feat(xai): Grok via grok.com subscription or API key#112
Merged
Conversation
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>
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.
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:
/provider xaiworks straight after/login xaiwith no profile to set up first. Profiles still shadow presets. Selecting a model on a preset no longer errors about a missing profile.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.