feat(xai): prefilled OAuth device link, SuperGrok login label, trimmed model list (#6734)

- Use verification_uri_complete from the xAI device-code response so the
  login link opens with the user code prefilled (https-validated)
- Add OAuthAuth.loginLabel and show "Sign in with SuperGrok or X Premium"
  in the xAI auth-type selector (threaded through lazyOAuth)
- Remove grok-3, grok-3-fast, grok-4.20 variants and grok-code-fast-1
  from the built-in xAI catalog and default to grok-4.5

Co-authored-by: Jaaneek <Jaaneek@users.noreply.github.com>
This commit is contained in:
Milosz Jankiewicz
2026-07-16 17:59:54 +01:00
committed by GitHub
parent c2c32febb0
commit a01baaaea7
15 changed files with 75 additions and 102 deletions
+2 -1
View File
@@ -31,7 +31,7 @@ export function envApiKeyAuth(name: string, envVars: readonly string[]): ApiKeyA
* of bundles by loading through a bundler-opaque dynamic import (variable
* specifier, see the bedrock lazy wrapper).
*/
export function lazyOAuth(input: { name: string; load: () => Promise<OAuthAuth> }): OAuthAuth {
export function lazyOAuth(input: { name: string; loginLabel?: string; load: () => Promise<OAuthAuth> }): OAuthAuth {
let promise: Promise<OAuthAuth> | undefined;
const loaded = () => {
promise ??= input.load();
@@ -39,6 +39,7 @@ export function lazyOAuth(input: { name: string; load: () => Promise<OAuthAuth>
};
return {
name: input.name,
loginLabel: input.loginLabel,
login: async (interaction) => (await loaded()).login(interaction),
refresh: async (credential) => (await loaded()).refresh(credential),
toAuth: async (credential) => (await loaded()).toAuth(credential),
+8 -1
View File
@@ -25,6 +25,7 @@ type XaiDeviceCode = {
deviceCode: string;
userCode: string;
verificationUri: string;
verificationUriComplete?: string;
intervalSeconds?: number;
expiresInSeconds: number;
};
@@ -110,10 +111,15 @@ function parseDeviceCode(body: JsonObject): XaiDeviceCode {
const interval = body.interval;
const intervalSeconds =
typeof interval === "number" && Number.isFinite(interval) && interval > 0 ? interval : undefined;
const verificationUriComplete =
typeof body.verification_uri_complete === "string" && body.verification_uri_complete.length > 0
? validateVerificationUri(body.verification_uri_complete)
: undefined;
return {
deviceCode: requiredString(body, "device_code"),
userCode: requiredString(body, "user_code"),
verificationUri: validateVerificationUri(requiredString(body, "verification_uri")),
verificationUriComplete,
intervalSeconds,
expiresInSeconds: positiveNumber(body, "expires_in"),
};
@@ -197,7 +203,7 @@ async function loginXai(interaction: AuthInteraction): Promise<OAuthCredential>
interaction.notify({
type: "device_code",
userCode: device.userCode,
verificationUri: device.verificationUri,
verificationUri: device.verificationUriComplete ?? device.verificationUri,
intervalSeconds: device.intervalSeconds,
expiresInSeconds: device.expiresInSeconds,
});
@@ -222,6 +228,7 @@ async function refreshXaiToken(refreshToken: string, signal?: AbortSignal): Prom
export const xaiOAuth: OAuthAuth = {
name: "xAI (Grok/X subscription)",
loginLabel: "Sign in with SuperGrok or X Premium",
login: loginXai,
refresh: (credential, signal) => refreshXaiToken(credential.refresh, signal),
+3
View File
@@ -190,6 +190,9 @@ export interface OAuthAuth {
/** Display name, e.g. "Anthropic (Claude Pro/Max)". */
name: string;
/** Selector label for the subscription login option, e.g. "Sign in with SuperGrok or X Premium". */
loginLabel?: string;
login(interaction: AuthInteraction): Promise<OAuthCredential>;
/**
-90
View File
@@ -4,78 +4,6 @@
import type { Model } from "../types.ts";
export const XAI_MODELS = {
"grok-3": {
id: "grok-3",
name: "Grok 3",
api: "openai-completions",
provider: "xai",
baseUrl: "https://api.x.ai/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
reasoning: false,
input: ["text"],
cost: {
input: 3,
output: 15,
cacheRead: 0.75,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 8192,
} satisfies Model<"openai-completions">,
"grok-3-fast": {
id: "grok-3-fast",
name: "Grok 3 Fast",
api: "openai-completions",
provider: "xai",
baseUrl: "https://api.x.ai/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
reasoning: false,
input: ["text"],
cost: {
input: 5,
output: 25,
cacheRead: 1.25,
cacheWrite: 0,
},
contextWindow: 131072,
maxTokens: 8192,
} satisfies Model<"openai-completions">,
"grok-4.20-0309-non-reasoning": {
id: "grok-4.20-0309-non-reasoning",
name: "Grok 4.20 (Non-Reasoning)",
api: "openai-completions",
provider: "xai",
baseUrl: "https://api.x.ai/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
reasoning: false,
input: ["text", "image"],
cost: {
input: 1.25,
output: 2.5,
cacheRead: 0.2,
cacheWrite: 0,
},
contextWindow: 1000000,
maxTokens: 30000,
} satisfies Model<"openai-completions">,
"grok-4.20-0309-reasoning": {
id: "grok-4.20-0309-reasoning",
name: "Grok 4.20 (Reasoning)",
api: "openai-completions",
provider: "xai",
baseUrl: "https://api.x.ai/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
reasoning: true,
input: ["text", "image"],
cost: {
input: 1.25,
output: 2.5,
cacheRead: 0.2,
cacheWrite: 0,
},
contextWindow: 1000000,
maxTokens: 30000,
} satisfies Model<"openai-completions">,
"grok-4.3": {
id: "grok-4.3",
name: "Grok 4.3",
@@ -131,22 +59,4 @@ export const XAI_MODELS = {
contextWindow: 256000,
maxTokens: 256000,
} satisfies Model<"openai-completions">,
"grok-code-fast-1": {
id: "grok-code-fast-1",
name: "Grok Code Fast 1",
api: "openai-completions",
provider: "xai",
baseUrl: "https://api.x.ai/v1",
compat: {"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false},
reasoning: false,
input: ["text"],
cost: {
input: 0.2,
output: 1.5,
cacheRead: 0.02,
cacheWrite: 0,
},
contextWindow: 32768,
maxTokens: 8192,
} satisfies Model<"openai-completions">,
} as const;
+5 -1
View File
@@ -12,7 +12,11 @@ export function xaiProvider(): Provider<"openai-completions" | "openai-responses
baseUrl: "https://api.x.ai/v1",
auth: {
apiKey: envApiKeyAuth("xAI API key", ["XAI_API_KEY"]),
oauth: lazyOAuth({ name: "xAI (Grok/X subscription)", load: loadXaiOAuth }),
oauth: lazyOAuth({
name: "xAI (Grok/X subscription)",
loginLabel: "Sign in with SuperGrok or X Premium",
load: loadXaiOAuth,
}),
},
models: Object.values(XAI_MODELS),
api: {