feat(grok-cli): add Grok CLI / Grok Build provider with OAuth device-code flow (#2502)

New OAuth provider routing through cli-chat-proxy.grok.com (OpenAI Responses
API), distinct from xai (api.x.ai) and grok-web (cookie SSO):

- Registry + GrokCliExecutor: Chat Completions -> Responses transform, CLI
  fingerprint headers, virtual effort models grok-4.5-{low,medium,high}
- OAuth device-code flow (auth.x.ai) with no-PKCE, shared xAI token refresh
- store=false multi-turn continuity via reasoning encrypted_content
- Quota tracker: on-demand window + prepaid balance on dashboard
- Connection test: 402 spending-limit = soft success (auth OK, out of credits)
- Alias/oauth/provider baselines + unit tests
This commit is contained in:
Fadjrir Herlambang
2026-07-10 11:47:08 +07:00
committed by decolua
parent c73c419d09
commit a11937cdd6
28 changed files with 2695 additions and 376 deletions
+2
View File
@@ -186,6 +186,8 @@ export const PATTERN_CAPABILITIES = [
// ── Grok (vision + Live Search) ──────────────────────────────────
{ pattern: "*grok*image*", caps: { imageOutput: true } },
{ pattern: "*grok-code*", caps: { reasoning: true, thinkingFormat: "openai", contextWindow: 256000 } },
// Grok 4.5 (Grok CLI / Grok Build): 500k context per cli-chat-proxy /v1/models
{ pattern: "*grok-4.5*", caps: { vision: true, reasoning: true, search: true, thinkingFormat: "openai", contextWindow: 500000, maxOutput: 64000 } },
{ pattern: "*grok-4*", caps: { vision: true, reasoning: true, search: true, thinkingFormat: "openai", contextWindow: 256000 } },
{ pattern: "*grok-3*", caps: { vision: true, reasoning: true, search: true, thinkingFormat: "openai", contextWindow: 131072 } },
{ pattern: "*grok*", caps: { vision: true, reasoning: true, search: true, thinkingFormat: "openai", contextWindow: 256000 } },
+86
View File
@@ -0,0 +1,86 @@
/**
* Grok CLI / Grok Build (cli-chat-proxy.grok.com)
*
* Source of truth: HAR capture of official grok-shell/grok-pager 0.2.93
* talking to https://cli-chat-proxy.grok.com (OpenAI Responses API).
*
* Distinct from:
* - `xai` → api.x.ai (API key / Grok Build OAuth PKCE)
* - `grok-web` → grok.com web SSO cookie
*/
export default {
id: "grok-cli",
priority: 275,
alias: "gcli",
aliases: ["grok-build", "gb"],
uiAlias: "gcli",
display: {
name: "Grok CLI (Grok Build)",
icon: "auto_awesome",
color: "#1DA1F2",
textIcon: "GC",
website: "https://x.ai",
notice: {
text: "Sign in with your xAI / Grok account via device code. Uses Grok Build subscription credits (cli-chat-proxy.grok.com).",
signupUrl: "https://grok.com/supergrok",
},
},
category: "oauth",
authModes: ["oauth"],
hasOAuth: true,
thinkingConfig: {
options: ["low", "medium", "high"],
defaultMode: "high",
},
transport: {
baseUrl: "https://cli-chat-proxy.grok.com/v1/responses",
format: "openai-responses",
forceStream: true,
modelsUrl: "https://cli-chat-proxy.grok.com/v1/models",
userUrl: "https://cli-chat-proxy.grok.com/v1/user",
billingUrl: "https://cli-chat-proxy.grok.com/v1/billing",
clientVersion: "0.2.93",
clientIdentifier: "grok-pager",
tokenAuth: "xai-grok-cli",
headers: {
"User-Agent": "grok-pager/0.2.93 grok-shell/0.2.93 (linux; x86_64)",
"x-xai-token-auth": "xai-grok-cli",
"x-grok-client-identifier": "grok-pager",
"x-grok-client-version": "0.2.93",
"x-authenticateresponse": "authenticate-response",
},
// Compaction threshold mirrored from CLI (x-compaction-at)
compactionAt: 400000,
// Quota tracker: official CLI polls billing?format=credits + user?include=subscription
usage: {
url: "https://cli-chat-proxy.grok.com/v1/billing?format=credits",
userUrl: "https://cli-chat-proxy.grok.com/v1/user?include=subscription",
},
retry: {
429: { attempts: 2, delayMs: 2000 },
502: { attempts: 2, delayMs: 1500 },
503: { attempts: 2, delayMs: 1500 },
},
},
models: [
{ id: "grok-4.5", name: "Grok 4.5" },
{ id: "grok-4.5-high", name: "Grok 4.5 (High)", upstreamModelId: "grok-4.5" },
{ id: "grok-4.5-medium", name: "Grok 4.5 (Medium)", upstreamModelId: "grok-4.5" },
{ id: "grok-4.5-low", name: "Grok 4.5 (Low)", upstreamModelId: "grok-4.5" },
],
features: {
usage: true,
},
oauth: {
// Same public client_id as Grok CLI / existing xai OAuth
clientId: "b1a00492-073a-47ea-816f-4c329264a828",
deviceCodeUrl: "https://auth.x.ai/oauth2/device/code",
tokenUrl: "https://auth.x.ai/oauth2/token",
refreshUrl: "https://auth.x.ai/oauth2/token",
// HAR scope includes conversations read/write beyond the api-only xai scope
scope:
"openid profile email offline_access grok-cli:access api:access conversations:read conversations:write",
referrer: "grok-build",
refreshLeadMs: 5 * 60 * 1000,
},
};
+60 -58
View File
@@ -1,4 +1,4 @@
// Auto-generated: static imports of all registry entries
// Auto-generated: static imports for all registry entries
import p0 from "./alicode-intl.js";
import p1 from "./alicode.js";
import p2 from "./anthropic.js";
@@ -41,62 +41,63 @@ import p38 from "./glm-cn.js";
import p39 from "./glm.js";
import p40 from "./google-pse.js";
import p41 from "./google-tts.js";
import p42 from "./grok-web.js";
import p43 from "./groq.js";
import p44 from "./huggingface.js";
import p45 from "./hyperbolic.js";
import p46 from "./iflow.js";
import p47 from "./inworld.js";
import p48 from "./jina-ai.js";
import p49 from "./jina-reader.js";
import p50 from "./kilocode.js";
import p51 from "./kimchi.js";
import p52 from "./kimi-coding.js";
import p53 from "./kimi.js";
import p54 from "./kiro.js";
import p55 from "./linkup.js";
import p56 from "./local-device.js";
import p57 from "./mimo-free.js";
import p58 from "./minimax-cn.js";
import p59 from "./minimax.js";
import p60 from "./mistral.js";
import p61 from "./mmf.js";
import p62 from "./nanobanana.js";
import p63 from "./nebius.js";
import p64 from "./nvidia.js";
import p65 from "./ollama-local.js";
import p66 from "./ollama.js";
import p67 from "./openai.js";
import p68 from "./opencode-go.js";
import p69 from "./opencode.js";
import p70 from "./openrouter.js";
import p71 from "./perplexity-web.js";
import p72 from "./perplexity.js";
import p73 from "./playht.js";
import p74 from "./qoder.js";
import p75 from "./qwen.js";
import p76 from "./recraft.js";
import p77 from "./runwayml.js";
import p78 from "./sdwebui.js";
import p79 from "./searchapi.js";
import p80 from "./searxng.js";
import p81 from "./serper.js";
import p82 from "./siliconflow.js";
import p83 from "./stability-ai.js";
import p84 from "./tavily.js";
import p85 from "./together.js";
import p86 from "./topaz.js";
import p87 from "./tortoise.js";
import p88 from "./venice.js";
import p89 from "./vercel-ai-gateway.js";
import p90 from "./vertex-partner.js";
import p91 from "./vertex.js";
import p92 from "./volcengine-ark.js";
import p93 from "./voyage-ai.js";
import p94 from "./xai.js";
import p95 from "./xiaomi-mimo.js";
import p96 from "./xiaomi-tokenplan.js";
import p97 from "./youcom.js";
import p42 from "./grok-cli.js";
import p43 from "./grok-web.js";
import p44 from "./groq.js";
import p45 from "./huggingface.js";
import p46 from "./hyperbolic.js";
import p47 from "./iflow.js";
import p48 from "./inworld.js";
import p49 from "./jina-ai.js";
import p50 from "./jina-reader.js";
import p51 from "./kilocode.js";
import p52 from "./kimchi.js";
import p53 from "./kimi-coding.js";
import p54 from "./kimi.js";
import p55 from "./kiro.js";
import p56 from "./linkup.js";
import p57 from "./local-device.js";
import p58 from "./mimo-free.js";
import p59 from "./minimax-cn.js";
import p60 from "./minimax.js";
import p61 from "./mistral.js";
import p62 from "./mmf.js";
import p63 from "./nanobanana.js";
import p64 from "./nebius.js";
import p65 from "./nvidia.js";
import p66 from "./ollama-local.js";
import p67 from "./ollama.js";
import p68 from "./openai.js";
import p69 from "./opencode-go.js";
import p70 from "./opencode.js";
import p71 from "./openrouter.js";
import p72 from "./perplexity-web.js";
import p73 from "./perplexity.js";
import p74 from "./playht.js";
import p75 from "./qoder.js";
import p76 from "./qwen.js";
import p77 from "./recraft.js";
import p78 from "./runwayml.js";
import p79 from "./sdwebui.js";
import p80 from "./searchapi.js";
import p81 from "./searxng.js";
import p82 from "./serper.js";
import p83 from "./siliconflow.js";
import p84 from "./stability-ai.js";
import p85 from "./tavily.js";
import p86 from "./together.js";
import p87 from "./topaz.js";
import p88 from "./tortoise.js";
import p89 from "./venice.js";
import p90 from "./vercel-ai-gateway.js";
import p91 from "./vertex-partner.js";
import p92 from "./vertex.js";
import p93 from "./volcengine-ark.js";
import p94 from "./voyage-ai.js";
import p95 from "./xai.js";
import p96 from "./xiaomi-mimo.js";
import p97 from "./xiaomi-tokenplan.js";
import p98 from "./youcom.js";
export default [
p0,
@@ -196,5 +197,6 @@ export default [
p94,
p95,
p96,
p97
p97,
p98,
];