Merge pull request #3310 from heathermhuang/codex/grok-subscription-support

feat: add grok subscription support
This commit is contained in:
Wesley Liddick
2026-06-26 15:41:52 +08:00
committed by GitHub
109 changed files with 5594 additions and 224 deletions
+121
View File
@@ -0,0 +1,121 @@
/**
* Admin Grok/xAI API endpoints
* Handles xAI OAuth flows for administrators.
*/
import { apiClient } from '../client'
export interface GrokAuthUrlResponse {
auth_url: string
session_id: string
state: string
}
export interface GrokAuthUrlRequest {
proxy_id?: number
redirect_uri?: string
}
export interface GrokExchangeCodeRequest {
session_id: string
state: string
code: string
proxy_id?: number
redirect_uri?: string
}
export interface GrokTokenInfo {
access_token?: string
refresh_token?: string
token_type?: string
id_token?: string
expires_at?: number | string
expires_in?: number
scope?: string
client_id?: string
email?: string
subscription_tier?: string
entitlement_status?: string
[key: string]: unknown
}
export interface GrokQuotaWindow {
limit?: number | null
remaining?: number | null
reset_unix?: number | null
reset_at?: string | null
}
export interface GrokQuotaSnapshot {
requests?: GrokQuotaWindow | null
tokens?: GrokQuotaWindow | null
retry_after_seconds?: number | null
subscription_tier?: string
entitlement_status?: string
status_code?: number
headers?: Record<string, string>
headers_observed: boolean
observation_source?: string
last_probe_at?: string
last_headers_seen_at?: string
updated_at: string
}
export interface GrokQuotaProbeResult {
source: 'active_probe'
snapshot?: GrokQuotaSnapshot | null
status_code?: number
headers_observed: boolean
reset_supported: boolean
fetched_at: number
}
export interface GrokQuotaResetResult {
supported: boolean
code: string
message: string
}
export async function generateAuthUrl(
payload: GrokAuthUrlRequest
): Promise<GrokAuthUrlResponse> {
const { data } = await apiClient.post<GrokAuthUrlResponse>(
'/admin/grok/oauth/auth-url',
payload
)
return data
}
export async function exchangeCode(payload: GrokExchangeCodeRequest): Promise<GrokTokenInfo> {
const { data } = await apiClient.post<GrokTokenInfo>(
'/admin/grok/oauth/exchange-code',
payload
)
return data
}
export async function refreshGrokToken(
refreshToken: string,
proxyId?: number | null
): Promise<GrokTokenInfo> {
const payload: Record<string, unknown> = { refresh_token: refreshToken }
if (proxyId) payload.proxy_id = proxyId
const { data } = await apiClient.post<GrokTokenInfo>(
'/admin/grok/oauth/refresh-token',
payload
)
return data
}
export async function queryQuota(id: number): Promise<GrokQuotaProbeResult> {
const { data } = await apiClient.get<GrokQuotaProbeResult>(`/admin/grok/accounts/${id}/quota`)
return data
}
export async function resetQuota(id: number): Promise<GrokQuotaResetResult> {
const { data } = await apiClient.post<GrokQuotaResetResult>(`/admin/grok/accounts/${id}/reset-quota`)
return data
}
export default { generateAuthUrl, exchangeCode, refreshGrokToken, queryQuota, resetQuota }
+3
View File
@@ -17,6 +17,7 @@ import subscriptionsAPI from './subscriptions'
import usageAPI from './usage'
import geminiAPI from './gemini'
import antigravityAPI from './antigravity'
import grokAPI from './grok'
import userAttributesAPI from './userAttributes'
import opsAPI from './ops'
import errorPassthroughAPI from './errorPassthrough'
@@ -51,6 +52,7 @@ export const adminAPI = {
usage: usageAPI,
gemini: geminiAPI,
antigravity: antigravityAPI,
grok: grokAPI,
userAttributes: userAttributesAPI,
ops: opsAPI,
errorPassthrough: errorPassthroughAPI,
@@ -83,6 +85,7 @@ export {
usageAPI,
geminiAPI,
antigravityAPI,
grokAPI,
userAttributesAPI,
opsAPI,
errorPassthroughAPI,
+2 -2
View File
@@ -17,7 +17,7 @@ export interface DefaultSubscriptionSetting {
}
// ── 平台限额类型 ──────────────────────────────────────────────────
export type PlatformType = "anthropic" | "openai" | "gemini" | "antigravity"
export type PlatformType = "anthropic" | "openai" | "gemini" | "antigravity" | "grok"
export type QuotaWindowType = "daily" | "weekly" | "monthly"
/** 单平台三档限额;null = 不限制,undefined = 未填(等价 null) */
@@ -30,7 +30,7 @@ export interface PlatformQuotaLimits {
/** 全平台默认限额 map(key = PlatformType) */
export type DefaultPlatformQuotasMap = Partial<Record<PlatformType, PlatformQuotaLimits>>
const PLATFORMS: PlatformType[] = ["anthropic", "openai", "gemini", "antigravity"]
const PLATFORMS: PlatformType[] = ["anthropic", "openai", "gemini", "antigravity", "grok"]
/** 归一化为全 4 平台 × 3 窗口(缺失填 null),供模板非空绑定 */
export function normalizePlatformQuotasMap(input?: DefaultPlatformQuotasMap | null): DefaultPlatformQuotasMap {
+1 -1
View File
@@ -307,7 +307,7 @@ export async function bindUserAuthIdentity(
/**
* Platform quota types
*/
export type PlatformQuotaPlatform = 'anthropic' | 'openai' | 'gemini' | 'antigravity'
export type PlatformQuotaPlatform = 'anthropic' | 'openai' | 'gemini' | 'antigravity' | 'grok'
export type PlatformQuotaWindow = 'daily' | 'weekly' | 'monthly'
export interface PlatformQuotaItem {