feat(grok-cli): show and redeem banked reset credits on Provider Limits (#12805)

Validado numa worktree combinada com as 16 PRs desta leva sobre `release/v3.8.51`: typecheck:core limpo, check-file-size e check-changelog-integrity OK, complexity 2788/3218 e cognitive 1261/1437 (ambos sob a baseline), ESLint 0 erros nos 152 arquivos alterados, 771 testes unitários focados, 49 de integração e a suíte vitest:ui completa (2149) verdes.

A decodificação dos campos aninhados 10/20/30 do `GetRemainingResets` ao vivo (último commit) é o que separa isto de um palpite sobre o formato do frame. Mostrar zero em vez de esconder a linha é a escolha certa: crédito zerado é informação, ausência de linha é ambiguidade.
This commit is contained in:
Bob.Hou
2026-09-07 07:58:12 -04:00
committed by GitHub
parent d7721559a0
commit c042a51884
14 changed files with 1516 additions and 26 deletions

View File

@@ -0,0 +1 @@
- **feat(grok-cli):** Provider Limits shows grok-cli banked reset credits from `GetRemainingResets` (including a real zero; a failed RPC omits the row) and the existing View credits button now calls `ConsumerUiSvc/RedeemReset` for grok-cli. Live tokens use nested fields 10/20/30 (id + Timestamp), not compact 1/2/3.

View File

@@ -0,0 +1,214 @@
/**
* grokResetCredits.ts — live read / redeem of Grok reset cards.
*
* POST grok.com/prod_mc_billing.ConsumerUiSvc/GetRemainingResets with the
* grok-cli OAuth bearer. Decode failure / HTTP miss returns null so callers
* omit bankedResetCredits rather than faking a zero. A decoded empty DATA
* frame with grpc-status 0 is a real zero and must be returned as count 0.
*
* Redeem: POST .../RedeemReset with ConsumerRedeemResetReq.token_id as
* protobuf field 10 (live X500 2026-09-05: fake field-10 → grpc-status 9
* "does not exist"; field 1 / empty → grpc-status 3 "Invalid token_id").
* Token ids stay server-side and are never logged.
*/
import {
decodeGrokGrpcWebRpc,
decodeGrokResetCreditsFrame,
encodeGrpcWebRequest,
encodeRedeemResetRequest,
type GrokResetCreditToken,
type GrokResetCreditsSnapshot,
} from "./grokResetCreditsFrame.ts";
const GROK_RESET_CREDITS_URL =
"https://grok.com/prod_mc_billing.ConsumerUiSvc/GetRemainingResets";
const GROK_REDEEM_RESET_URL = "https://grok.com/prod_mc_billing.ConsumerUiSvc/RedeemReset";
const GRPC_WEB_EMPTY_REQUEST_FRAME = Buffer.from([0, 0, 0, 0, 0]);
const FETCH_TIMEOUT_MS = 8_000;
const REDEEM_TIMEOUT_MS = 15_000;
export type GrokResetCreditOutcome = "reset" | "alreadyRedeemed";
export type GrokRedeemMappedStatus = GrokResetCreditOutcome | "noCredit";
export class GrokResetCreditError extends Error {
status: number;
code: string;
constructor(status: number, code: string, message: string) {
super(message);
this.name = "GrokResetCreditError";
this.status = status;
this.code = code;
}
}
export type PublicGrokResetCredit = {
selectionToken: string;
expiresAt: string | null;
};
function grokRpcHeaders(accessToken: string): Record<string, string> {
return {
Authorization: ["Bearer", accessToken].join(" "),
"Content-Type": "application/grpc-web+proto",
"X-Grpc-Web": "1",
};
}
function expirySortValue(expiresAt: string | null): number {
if (!expiresAt) return Number.POSITIVE_INFINITY;
const ms = Date.parse(expiresAt);
return Number.isFinite(ms) ? ms : Number.POSITIVE_INFINITY;
}
function toPublicCredits(tokens: GrokResetCreditToken[]): PublicGrokResetCredit[] {
return tokens
.map((token, index) => ({ token, index }))
.sort(
(left, right) =>
expirySortValue(left.token.expiresAt) - expirySortValue(right.token.expiresAt) ||
left.index - right.index
)
.map(({ token }) => ({
selectionToken: token.tokenId,
expiresAt: token.expiresAt,
}));
}
async function postGrokRpc(
url: string,
accessToken: string,
payload: Buffer,
fetchImpl: typeof fetch,
timeoutMs: number
): Promise<{ grpcStatus: string; grpcMessage: string | null }> {
const response = await fetchImpl(url, {
method: "POST",
headers: grokRpcHeaders(accessToken),
body: new Uint8Array(encodeGrpcWebRequest(payload)),
signal: AbortSignal.timeout(timeoutMs),
});
if (!response.ok) {
throw new GrokResetCreditError(
response.status,
"grok_reset_credit_upstream_error",
`Grok reset-credit API returned HTTP ${response.status}.`
);
}
const buffer = Buffer.from(await response.arrayBuffer());
return decodeGrokGrpcWebRpc(
buffer,
response.headers.get("grpc-status"),
response.headers.get("grpc-message")
);
}
export function mapGrokRedeemGrpcStatus(
grpcStatus: string,
grpcMessage: string | null
): GrokRedeemMappedStatus {
if (grpcStatus === "0") return "reset";
const message = (grpcMessage ?? "").toLowerCase();
if (grpcStatus === "9") {
return message.includes("already") ? "alreadyRedeemed" : "noCredit";
}
if (grpcStatus === "3" && message.includes("token_id")) {
return "noCredit";
}
throw new GrokResetCreditError(
502,
"unknown_reset_credit_response",
grpcMessage ? `Grok reset failed: ${grpcMessage}` : `Grok reset failed (grpc-status ${grpcStatus})`
);
}
function throwMappedRedeemStatus(outcome: GrokRedeemMappedStatus): GrokResetCreditOutcome {
if (outcome === "noCredit") {
throw new GrokResetCreditError(409, "no_credit", "No Grok reset credits are available.");
}
return outcome;
}
export async function fetchGrokResetCredits(
accessToken: string,
fetchImpl: typeof fetch = fetch
): Promise<GrokResetCreditsSnapshot | null> {
if (!accessToken) return null;
try {
const response = await fetchImpl(GROK_RESET_CREDITS_URL, {
method: "POST",
headers: grokRpcHeaders(accessToken),
body: GRPC_WEB_EMPTY_REQUEST_FRAME,
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
});
if (!response.ok) return null;
const decoded = decodeGrokResetCreditsFrame(Buffer.from(await response.arrayBuffer()));
return decoded.ok ? decoded.snapshot : null;
} catch {
return null;
}
}
async function loadInventory(
accessToken: string,
fetchImpl: typeof fetch
): Promise<{ credits: PublicGrokResetCredit[]; availableCount: number }> {
const response = await fetchImpl(GROK_RESET_CREDITS_URL, {
method: "POST",
headers: grokRpcHeaders(accessToken),
body: GRPC_WEB_EMPTY_REQUEST_FRAME,
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
});
if (!response.ok) {
throw new GrokResetCreditError(
response.status,
"grok_reset_credit_upstream_error",
`Grok remaining-resets returned HTTP ${response.status}.`
);
}
const decoded = decodeGrokResetCreditsFrame(Buffer.from(await response.arrayBuffer()));
if (!decoded.ok) {
throw new GrokResetCreditError(502, "grok_reset_credit_decode_failed", "Grok remaining-resets decode failed.");
}
const credits = toPublicCredits(decoded.tokens);
return { credits, availableCount: credits.length };
}
export async function listGrokResetCreditTokens(
accessToken: string,
fetchImpl: typeof fetch = fetch
): Promise<{ credits: PublicGrokResetCredit[]; availableCount: number }> {
if (!accessToken) {
throw new GrokResetCreditError(401, "grok_access_token_missing", "Grok OAuth access token is missing.");
}
return loadInventory(accessToken, fetchImpl);
}
export async function consumeGrokResetCredit(
accessToken: string,
options: { tokenId?: string } = {},
fetchImpl: typeof fetch = fetch
): Promise<GrokResetCreditOutcome> {
if (!accessToken) {
throw new GrokResetCreditError(401, "grok_access_token_missing", "Grok OAuth access token is missing.");
}
const requested = options.tokenId?.trim() ?? "";
let selectedTokenId = requested;
if (!selectedTokenId) {
const inventory = await loadInventory(accessToken, fetchImpl);
selectedTokenId = inventory.credits[0]?.selectionToken ?? "";
}
if (!selectedTokenId) {
throw new GrokResetCreditError(409, "no_credit", "No Grok reset credits are available.");
}
const rpc = await postGrokRpc(
GROK_REDEEM_RESET_URL,
accessToken,
encodeRedeemResetRequest(selectedTokenId),
fetchImpl,
REDEEM_TIMEOUT_MS
);
return throwMappedRedeemStatus(mapGrokRedeemGrpcStatus(rpc.grpcStatus, rpc.grpcMessage));
}

View File

@@ -0,0 +1,346 @@
/**
* grokResetCreditsFrame.ts — gRPC-web decoder for
* `prod_mc_billing.ConsumerUiSvc/GetRemainingResets`.
*
* Live shape (X500, 2026-09-06 hotmail SuperGrokPro): empty DATA +
* grpc-status 0 = inventory 0; otherwise repeated top-level field 10,
* each a ConsumerResetToken. Nested numbers are 10 / 20 / 30, all
* length-delimited (id 13B string, granted/expires google.protobuf.Timestamp
* with seconds in field 1). Compact 1 / 2 / 3 (id bytes, granted/expires
* varint unix seconds) is still accepted. Token ids stay server-side.
*
* Do not reuse grokCliQuotaFrame.decodeFields: that Map last-wins and
* would collapse repeated field 10 to a single token.
*/
import { probeFrameHeader } from "./grokCliQuotaFrame.ts";
const WIRE_TYPE_VARINT = 0;
const WIRE_TYPE_FIXED64 = 1;
const WIRE_TYPE_LENGTH_DELIMITED = 2;
const WIRE_TYPE_FIXED32 = 5;
const GRPC_WEB_TRAILER_FLAG_BIT = 0x80;
const MAX_VARINT_SHIFT_BITS = 70n;
const FIELD_RESET_TOKEN = 10;
/** Compact 1/2/3 (varint seconds) and live 10/20/30 (id + Timestamp). */
const TOKEN_NESTED_FIELDS = {
id: [1, 10],
granted: [2, 20],
expires: [3, 30],
} as const;
const TIMESTAMP_FIELD_SECONDS = 1;
const REDEEM_REQUEST_TOKEN_ID_FIELD = 10;
type ProtoField =
| { wireType: typeof WIRE_TYPE_VARINT; value: number }
| {
wireType: typeof WIRE_TYPE_FIXED64 | typeof WIRE_TYPE_FIXED32 | typeof WIRE_TYPE_LENGTH_DELIMITED;
bytes: Buffer;
};
type TaggedField = { fieldNumber: number; field: ProtoField };
export type GrokResetCreditsSnapshot = {
count: number;
nextExpiresAt: string | null;
};
export type GrokResetCreditToken = {
tokenId: string;
expiresAt: string | null;
};
export type GrokResetCreditsDecode =
| { ok: true; snapshot: GrokResetCreditsSnapshot; tokens: GrokResetCreditToken[] }
| { ok: false; reason: "empty-buffer" | "no-data-frame" | "malformed" | "trailer-nonzero" };
function encodeVarint(value: number): Buffer {
const bytes: number[] = [];
let n = Math.floor(value);
while (n > 0x7f) {
bytes.push((n & 0x7f) | 0x80);
n = Math.floor(n / 128);
}
bytes.push(n);
return Buffer.from(bytes);
}
/**
* ConsumerRedeemResetReq.token_id is field 10 (live X500 2026-09-05:
* fake field-10 id → grpc-status 9 "does not exist"; field 1 / empty →
* grpc-status 3 "Invalid token_id").
*/
export function encodeRedeemResetRequest(tokenId: string): Buffer {
const body = Buffer.from(tokenId, "utf8");
return Buffer.concat([
encodeVarint((REDEEM_REQUEST_TOKEN_ID_FIELD << 3) | WIRE_TYPE_LENGTH_DELIMITED),
encodeVarint(body.length),
body,
]);
}
export function encodeGrpcWebRequest(payload: Buffer): Buffer {
const header = Buffer.alloc(5);
header.writeUInt32BE(payload.length, 1);
return Buffer.concat([header, payload]);
}
function readVarint(buffer: Buffer, offset: number): { value: number; next: number } | null {
let result = 0n;
let shift = 0n;
let pos = offset;
for (;;) {
if (pos >= buffer.length) return null;
const byte = buffer[pos];
result |= BigInt(byte & 0x7f) << shift;
pos += 1;
if ((byte & 0x80) === 0) break;
shift += 7n;
if (shift > MAX_VARINT_SHIFT_BITS) return null;
}
return { value: Number(result), next: pos };
}
function readField(buffer: Buffer, offset: number): { tagged: TaggedField; next: number } | null {
const tagResult = readVarint(buffer, offset);
if (!tagResult) return null;
const fieldNumber = tagResult.value >>> 3;
const wireType = tagResult.value & 0x7;
if (fieldNumber === 0) return null;
if (wireType === WIRE_TYPE_VARINT) {
const valueResult = readVarint(buffer, tagResult.next);
if (!valueResult) return null;
return {
tagged: { fieldNumber, field: { wireType: WIRE_TYPE_VARINT, value: valueResult.value } },
next: valueResult.next,
};
}
if (wireType === WIRE_TYPE_LENGTH_DELIMITED) {
const lengthResult = readVarint(buffer, tagResult.next);
if (!lengthResult) return null;
const { value: length, next: bodyStart } = lengthResult;
if (length < 0 || bodyStart + length > buffer.length) return null;
return {
tagged: {
fieldNumber,
field: { wireType: WIRE_TYPE_LENGTH_DELIMITED, bytes: buffer.subarray(bodyStart, bodyStart + length) },
},
next: bodyStart + length,
};
}
if (wireType === WIRE_TYPE_FIXED64) {
if (tagResult.next + 8 > buffer.length) return null;
return {
tagged: {
fieldNumber,
field: { wireType: WIRE_TYPE_FIXED64, bytes: buffer.subarray(tagResult.next, tagResult.next + 8) },
},
next: tagResult.next + 8,
};
}
if (wireType === WIRE_TYPE_FIXED32) {
if (tagResult.next + 4 > buffer.length) return null;
return {
tagged: {
fieldNumber,
field: { wireType: WIRE_TYPE_FIXED32, bytes: buffer.subarray(tagResult.next, tagResult.next + 4) },
},
next: tagResult.next + 4,
};
}
return null;
}
function walkFields(buffer: Buffer): TaggedField[] | null {
const fields: TaggedField[] = [];
let offset = 0;
while (offset < buffer.length) {
const result = readField(buffer, offset);
if (!result) return null;
fields.push(result.tagged);
offset = result.next;
}
return fields;
}
function decodeTrailerMessage(raw: string | null): string | null {
if (!raw) return null;
try {
return decodeURIComponent(raw.replace(/\+/g, " "));
} catch {
return raw;
}
}
function parseTrailer(trailerBody: Buffer): { status: number | null; message: string | null } {
const text = trailerBody.toString("utf8");
const statusMatch = text.match(/grpc-status:\s*(\d+)/);
const messageMatch = text.match(/grpc-message:\s*([^\r\n]+)/);
return {
status: statusMatch ? Number(statusMatch[1]) : null,
message: decodeTrailerMessage(messageMatch?.[1] ?? null),
};
}
export function decodeGrokGrpcWebRpc(
buffer: Buffer,
headerStatus?: string | null,
headerMessage?: string | null
): { grpcStatus: string; grpcMessage: string | null } {
let trailerStatus: number | null = null;
let trailerMessage: string | null = null;
let offset = 0;
while (offset < buffer.length) {
const frame = probeFrameHeader(buffer, offset);
if (!frame) break;
const frameEnd = frame.payloadStart + frame.payloadLength;
const body = buffer.subarray(frame.payloadStart, frameEnd);
if ((frame.flag & GRPC_WEB_TRAILER_FLAG_BIT) !== 0) {
const parsed = parseTrailer(body);
if (parsed.status !== null) trailerStatus = parsed.status;
if (parsed.message) trailerMessage = parsed.message;
}
offset = frameEnd;
}
const grpcStatus =
trailerStatus !== null ? String(trailerStatus) : headerStatus && headerStatus.trim() ? headerStatus.trim() : "13";
const grpcMessage = trailerMessage ?? decodeTrailerMessage(headerMessage ?? null);
return { grpcStatus, grpcMessage };
}
function splitFrames(buffer: Buffer): {
dataPayload: Buffer | null;
sawData: boolean;
trailerStatus: number | null;
} {
let offset = 0;
let dataPayload: Buffer | null = null;
let sawData = false;
let trailerStatus: number | null = null;
while (offset < buffer.length) {
const frame = probeFrameHeader(buffer, offset);
if (!frame) break;
const frameEnd = frame.payloadStart + frame.payloadLength;
const body = buffer.subarray(frame.payloadStart, frameEnd);
if ((frame.flag & GRPC_WEB_TRAILER_FLAG_BIT) !== 0) {
const status = parseTrailer(body).status;
if (status !== null) trailerStatus = status;
} else if (!sawData) {
sawData = true;
dataPayload = body;
}
offset = frameEnd;
}
return { dataPayload, sawData, trailerStatus };
}
function timestampSeconds(field: ProtoField): number | null {
if (field.wireType === WIRE_TYPE_VARINT) {
return Number.isFinite(field.value) ? field.value : null;
}
if (field.wireType !== WIRE_TYPE_LENGTH_DELIMITED) return null;
const nested = walkFields(field.bytes);
if (!nested) return null;
const seconds = nested.find(
(item) => item.fieldNumber === TIMESTAMP_FIELD_SECONDS && item.field.wireType === WIRE_TYPE_VARINT
);
if (!seconds || seconds.field.wireType !== WIRE_TYPE_VARINT) return null;
return Number.isFinite(seconds.field.value) ? seconds.field.value : null;
}
function hasFieldNumber(field: TaggedField, numbers: readonly number[]): boolean {
return (numbers as readonly number[]).includes(field.fieldNumber);
}
function tokenExpiresAtMs(tokenFields: TaggedField[]): number | null {
const expires = tokenFields.find((field) => hasFieldNumber(field, TOKEN_NESTED_FIELDS.expires));
if (!expires) return null;
const seconds = timestampSeconds(expires.field);
return seconds === null ? null : seconds * 1000;
}
function tokenIdFromFields(tokenFields: TaggedField[]): string | null {
const id = tokenFields.find(
(field) =>
hasFieldNumber(field, TOKEN_NESTED_FIELDS.id) &&
field.field.wireType === WIRE_TYPE_LENGTH_DELIMITED
);
if (!id || id.field.wireType !== WIRE_TYPE_LENGTH_DELIMITED) return null;
const tokenId = id.field.bytes.toString("utf8").trim();
return tokenId.length > 0 ? tokenId : null;
}
function inventoryFromPayload(
payload: Buffer,
nowMs: number
): { snapshot: GrokResetCreditsSnapshot; tokens: GrokResetCreditToken[] } | null {
if (payload.length === 0) {
return { snapshot: { count: 0, nextExpiresAt: null }, tokens: [] };
}
const top = walkFields(payload);
if (!top) return null;
const tokens: GrokResetCreditToken[] = [];
const expiresMs: number[] = [];
for (const tagged of top) {
if (tagged.fieldNumber !== FIELD_RESET_TOKEN) continue;
if (tagged.field.wireType !== WIRE_TYPE_LENGTH_DELIMITED) return null;
const tokenFields = walkFields(tagged.field.bytes);
if (!tokenFields) return null;
const tokenId = tokenIdFromFields(tokenFields);
if (!tokenId) return null;
const expires = tokenExpiresAtMs(tokenFields);
if (expires !== null && expires < nowMs) continue;
tokens.push({
tokenId,
expiresAt: expires === null ? null : new Date(expires).toISOString(),
});
if (expires !== null) expiresMs.push(expires);
}
const next = expiresMs.length > 0 ? Math.min(...expiresMs) : null;
return {
snapshot: {
count: tokens.length,
nextExpiresAt: next === null ? null : new Date(next).toISOString(),
},
tokens,
};
}
export function decodeGrokResetCreditsFrame(
buffer: Buffer,
nowMs = Date.now()
): GrokResetCreditsDecode {
if (!buffer || buffer.length === 0) {
return { ok: false, reason: "empty-buffer" };
}
try {
const framed = probeFrameHeader(buffer, 0) !== null;
if (!framed) {
const inventory = inventoryFromPayload(buffer, nowMs);
if (!inventory) return { ok: false, reason: "malformed" };
return { ok: true, ...inventory };
}
const { dataPayload, sawData, trailerStatus } = splitFrames(buffer);
if (trailerStatus !== null && trailerStatus !== 0) {
return { ok: false, reason: "trailer-nonzero" };
}
if (!sawData || dataPayload === null) {
return { ok: false, reason: "no-data-frame" };
}
const inventory = inventoryFromPayload(dataPayload, nowMs);
if (!inventory) return { ok: false, reason: "malformed" };
return { ok: true, ...inventory };
} catch {
return { ok: false, reason: "malformed" };
}
}

View File

@@ -5,6 +5,7 @@ import {
GROK_BUILD_ADDITIONAL_CREDITS_URL,
type GrokAutoTopUpStatus,
} from "../../../src/shared/utils/grokBilling.ts";
import { fetchGrokResetCredits } from "../grokResetCredits.ts";
const GROK_BUILD_FETCH_TIMEOUT_MS = 10_000;
const GROK_BUILD_MAX_RESPONSE_BYTES = 256 * 1024;
@@ -223,11 +224,13 @@ export async function getGrokCliUsage(accessToken?: string) {
const user = await fetchGrokBuildJson("/user?include=subscription", baseHeaders, userSchema);
const userId = user?.userId || null;
const tier = user?.subscriptionTier || null;
const billing = await fetchGrokBuildJson(
"/billing?format=credits",
userId ? getGrokBuildModelsHeaders({ token: accessToken, userId }) : baseHeaders,
billingSchema
);
const billingHeaders = userId
? getGrokBuildModelsHeaders({ token: accessToken, userId })
: baseHeaders;
const [billing, resetCredits] = await Promise.all([
fetchGrokBuildJson("/billing?format=credits", billingHeaders, billingSchema),
fetchGrokResetCredits(accessToken),
]);
if (!billing?.config) {
return {
@@ -258,6 +261,7 @@ export async function getGrokCliUsage(accessToken?: string) {
return {
quotas,
...(tier ? { plan: tier } : {}),
...(resetCredits ? { bankedResetCredits: resetCredits.count } : {}),
billing: {
currency: "USD",
...(config.prepaidBalance ? { extraCreditsMinorUnits: config.prepaidBalance.val } : {}),

View File

@@ -147,7 +147,12 @@ function normalizeQuotaEntry(name: string, quota: any = {}, extras: any = {}) {
}
function parseGeneric(data: any) {
return quotaEntries(data).map(([name, quota]) => normalizeQuotaEntry(name, quota));
const quotas = quotaEntries(data).map(([name, quota]) => normalizeQuotaEntry(name, quota));
const bankedResetCredits = Number(data?.bankedResetCredits);
if (Number.isFinite(bankedResetCredits) && bankedResetCredits >= 0) {
quotas.push(buildBankedResetCreditsQuota(bankedResetCredits));
}
return quotas;
}
function parseGithub(data: any) {

View File

@@ -80,7 +80,12 @@ function useOpenCodexResetCredits(
const notify = useNotificationStore();
return useCallback(
async (connectionId: string, provider: string) => {
if (provider !== "codex" || loadingResetCreditsId || redeemingResetCreditId) return;
if (
(provider !== "codex" && provider !== "grok-cli") ||
loadingResetCreditsId ||
redeemingResetCreditId
)
return;
setLoadingResetCreditsId(connectionId);
setErrors((prev) => ({ ...prev, [connectionId]: null }));
try {

View File

@@ -339,7 +339,7 @@ export function computeCanEditCutoff(quotas: any[]): boolean {
export function computeCanRedeemResetCredit(provider: string, quotas: any[]): boolean {
return (
provider === "codex" &&
(provider === "codex" || provider === "grok-cli") &&
quotas.some((q: any) => q?.isResetCredits && Number(q.creditCount ?? q.remaining ?? 0) > 0)
);
}

View File

@@ -7,6 +7,12 @@ import {
consumeCodexResetCredit,
listCodexResetCredits,
} from "@/lib/usage/codexResetCredits";
import {
GrokResetCreditError,
consumeGrokResetCredit,
listGrokResetCredits,
} from "@/lib/usage/grokResetCredits";
import { getProviderConnectionById } from "@/lib/db/providers";
const ConnectionIdSchema = z.string().trim().min(1).max(256);
@@ -16,17 +22,40 @@ const CodexResetCreditBodySchema = z.object({
creditId: z.string().trim().min(1).max(512).optional(),
});
function isResetCreditError(
error: unknown
): error is CodexResetCreditError | GrokResetCreditError {
return error instanceof CodexResetCreditError || error instanceof GrokResetCreditError;
}
function buildErrorResponse(error: unknown) {
const status = error instanceof CodexResetCreditError ? error.status : 500;
const code = error instanceof CodexResetCreditError ? error.code : "codex_reset_credit_failed";
const message =
error instanceof CodexResetCreditError
? sanitizeErrorMessage(error.message) || "Codex reset-credit request failed."
: "Codex reset-credit request failed.";
const status = isResetCreditError(error) ? error.status : 500;
const code = isResetCreditError(error) ? error.code : "reset_credit_failed";
const message = isResetCreditError(error)
? sanitizeErrorMessage(error.message) || "Reset-credit request failed."
: "Reset-credit request failed.";
console.error("[API] /api/usage/codex-reset-credit error:", error);
return NextResponse.json({ ok: false, code, error: message }, { status });
}
function unsupportedResetCreditProvider(provider: string | null) {
return NextResponse.json(
{
ok: false,
code: provider ? "unsupported_reset_credit_provider" : "connection_not_found",
error: provider
? "Reset credits are only available for Codex and Grok Build accounts."
: "Connection not found.",
},
{ status: provider ? 400 : 404 }
);
}
async function resolveResetCreditProvider(connectionId: string): Promise<string | null> {
const connection = await getProviderConnectionById(connectionId);
return connection && typeof connection.provider === "string" ? connection.provider : null;
}
export async function GET(request: Request) {
const authError = await requireManagementAuth(request);
if (authError) return authError;
@@ -41,8 +70,16 @@ export async function GET(request: Request) {
{ status: 400 }
);
}
const result = await listCodexResetCredits(parsed.data);
return NextResponse.json({ ok: true, ...result });
const provider = await resolveResetCreditProvider(parsed.data);
if (provider === "grok-cli") {
const result = await listGrokResetCredits(parsed.data);
return NextResponse.json({ ok: true, ...result });
}
if (provider === "codex") {
const result = await listCodexResetCredits(parsed.data);
return NextResponse.json({ ok: true, ...result });
}
return unsupportedResetCreditProvider(provider);
} catch (error) {
return buildErrorResponse(error);
}
@@ -62,12 +99,24 @@ export async function POST(request: Request) {
);
}
const result = await consumeCodexResetCredit(
parsed.data.connectionId,
parsed.data.idempotencyKey,
parsed.data.creditId
);
return NextResponse.json({ ok: true, ...result });
const provider = await resolveResetCreditProvider(parsed.data.connectionId);
if (provider === "grok-cli") {
const result = await consumeGrokResetCredit(
parsed.data.connectionId,
parsed.data.idempotencyKey,
parsed.data.creditId
);
return NextResponse.json({ ok: true, ...result });
}
if (provider === "codex") {
const result = await consumeCodexResetCredit(
parsed.data.connectionId,
parsed.data.idempotencyKey,
parsed.data.creditId
);
return NextResponse.json({ ok: true, ...result });
}
return unsupportedResetCreditProvider(provider);
} catch (error) {
return buildErrorResponse(error);
}

View File

@@ -0,0 +1,143 @@
import { getProviderConnectionById } from "@/lib/db/providers";
import { isConnectionUnavailableToAuxiliaryActivity } from "@/lib/exclusiveLeaseIsolation";
import {
fetchAndPersistProviderLimits,
refreshAndUpdateCredentials,
} from "@/lib/usage/providerLimits";
import { invalidateGrokCliQuotaCache } from "@omniroute/open-sse/services/grokCliQuotaFetcher.ts";
import {
consumeGrokResetCredit as consumeGrokResetCreditRpc,
GrokResetCreditError,
listGrokResetCreditTokens,
type GrokResetCreditOutcome,
type PublicGrokResetCredit,
} from "@omniroute/open-sse/services/grokResetCredits.ts";
import { sanitizeErrorMessage } from "@omniroute/open-sse/utils/error.ts";
export { GrokResetCreditError };
type JsonRecord = Record<string, unknown>;
type GrokConnectionLike = JsonRecord & {
id: string;
provider: string;
authType?: string;
accessToken?: string;
};
export interface GrokResetCreditList {
credits: PublicGrokResetCredit[];
availableCount: number;
}
async function loadGrokConnection(connectionId: string): Promise<GrokConnectionLike> {
if (await isConnectionUnavailableToAuxiliaryActivity(connectionId)) {
throw new GrokResetCreditError(
409,
"exclusive_lease_active",
"Reset-credit operations are deferred while an exclusive lease is active."
);
}
const connection = (await getProviderConnectionById(
connectionId
)) as unknown as GrokConnectionLike | null;
if (!connection) {
throw new GrokResetCreditError(404, "connection_not_found", "Connection not found.");
}
if (connection.provider !== "grok-cli") {
throw new GrokResetCreditError(
400,
"grok_provider_required",
"Reset credits can only be redeemed for Grok Build accounts."
);
}
if (connection.authType !== "oauth") {
throw new GrokResetCreditError(
400,
"grok_oauth_required",
"Grok reset credits require an OAuth connection."
);
}
return connection;
}
async function refreshGrokConnectionIfNeeded(
connection: GrokConnectionLike,
force = false
): Promise<GrokConnectionLike> {
const refreshed = await refreshAndUpdateCredentials(connection, {
allowRotatingRefresh: true,
force,
});
return refreshed.connection as GrokConnectionLike;
}
function requireAccessToken(connection: GrokConnectionLike): string {
const token = typeof connection.accessToken === "string" ? connection.accessToken.trim() : "";
if (!token) {
throw new GrokResetCreditError(
401,
"grok_access_token_missing",
"Grok OAuth access token is missing."
);
}
return token;
}
export async function listGrokResetCredits(connectionId: string): Promise<GrokResetCreditList> {
if (!connectionId || typeof connectionId !== "string") {
throw new GrokResetCreditError(400, "connection_id_required", "connectionId is required.");
}
try {
let connection = await loadGrokConnection(connectionId);
connection = await refreshGrokConnectionIfNeeded(connection);
return await listGrokResetCreditTokens(requireAccessToken(connection));
} catch (error) {
if (error instanceof GrokResetCreditError) throw error;
throw new GrokResetCreditError(
500,
"grok_reset_credit_list_failed",
sanitizeErrorMessage(error) || "Failed to load Grok reset credits."
);
}
}
export async function consumeGrokResetCredit(
connectionId: string,
// RedeemReset has no idempotency field (live X500 2026-09-05). Kept so the
// shared /api/usage/codex-reset-credit body schema stays one shape.
_idempotencyKey: string,
creditId?: string
): Promise<{
outcome: GrokResetCreditOutcome;
usage: JsonRecord;
}> {
if (!connectionId || typeof connectionId !== "string") {
throw new GrokResetCreditError(400, "connection_id_required", "connectionId is required.");
}
try {
let connection = await loadGrokConnection(connectionId);
connection = await refreshGrokConnectionIfNeeded(connection);
const outcome = await consumeGrokResetCreditRpc(requireAccessToken(connection), {
tokenId: creditId,
});
invalidateGrokCliQuotaCache(connectionId);
const refreshed = await fetchAndPersistProviderLimits(connectionId, "manual", {
allowRotatingRefresh: true,
});
return { outcome, usage: refreshed.usage };
} catch (error) {
if (error instanceof GrokResetCreditError) throw error;
throw new GrokResetCreditError(
500,
"grok_reset_credit_failed",
sanitizeErrorMessage(error) || "Failed to redeem Grok reset credit."
);
}
}

View File

@@ -32,6 +32,75 @@ function response(value: unknown, init: ResponseInit = {}) {
});
}
function grpcFrame(flag: number, payload: Buffer): Buffer {
const header = Buffer.alloc(5);
header[0] = flag;
header.writeUInt32BE(payload.length, 1);
return Buffer.concat([header, payload]);
}
function emptyResetCreditsResponse(): Response {
const trailer = Buffer.from("grpc-status:0\r\n", "utf8");
return new Response(Buffer.concat([grpcFrame(0x00, Buffer.alloc(0)), grpcFrame(0x80, trailer)]), {
status: 200,
headers: { "content-type": "application/grpc-web+proto" },
});
}
function encodeVarint(value: number): Buffer {
const bytes: number[] = [];
let v = BigInt(value);
do {
let byte = Number(v & 0x7fn);
v >>= 7n;
if (v !== 0n) byte |= 0x80;
bytes.push(byte);
} while (v !== 0n);
return Buffer.from(bytes);
}
function encodeTag(fieldNumber: number, wireType: number): Buffer {
return encodeVarint((fieldNumber << 3) | wireType);
}
function encodeLengthDelimited(fieldNumber: number, body: Buffer): Buffer {
return Buffer.concat([encodeTag(fieldNumber, 2), encodeVarint(body.length), body]);
}
function encodeVarintField(fieldNumber: number, value: number): Buffer {
return Buffer.concat([encodeTag(fieldNumber, 0), encodeVarint(value)]);
}
function oneResetTokenResponse(): Response {
const token = Buffer.concat([
encodeLengthDelimited(1, Buffer.from("test-token-id", "utf8")),
encodeVarintField(2, 1786560540),
encodeVarintField(3, 1789238940),
]);
const payload = encodeLengthDelimited(10, token);
const trailer = Buffer.from("grpc-status:0\r\n", "utf8");
return new Response(Buffer.concat([grpcFrame(0x00, payload), grpcFrame(0x80, trailer)]), {
status: 200,
headers: { "content-type": "application/grpc-web+proto" },
});
}
/** Live X500 hotmail shape: nested fields 10/20/30, timestamps length-delimited. */
function liveResetTokenResponse(): Response {
const timestamp = (unixSeconds: number) => encodeVarintField(1, unixSeconds);
const token = Buffer.concat([
encodeLengthDelimited(10, Buffer.from("test-token-id", "utf8")),
encodeLengthDelimited(20, timestamp(1786560540)),
encodeLengthDelimited(30, timestamp(1789238940)),
]);
const payload = encodeLengthDelimited(10, token);
const trailer = Buffer.from("grpc-status:0\r\n", "utf8");
return new Response(Buffer.concat([grpcFrame(0x00, payload), grpcFrame(0x80, trailer)]), {
status: 200,
headers: { "content-type": "application/grpc-web+proto" },
});
}
function successFixtures(
options: {
tier?: unknown;
@@ -99,6 +168,9 @@ function successFixtures(
},
});
}
if (url.includes("prod_mc_billing.ConsumerUiSvc/GetRemainingResets")) {
return emptyResetCreditsResponse();
}
return new Response(null, { status: 404 });
};
}
@@ -106,6 +178,7 @@ function successFixtures(
interface UsageResult {
plan?: string;
message?: string;
bankedResetCredits?: number;
quotas?: Record<
string,
{
@@ -190,15 +263,35 @@ test("grok-cli fetches the fixed read-only surfaces with the full Grok client pr
additionalCreditsUrl: "https://grok.com/build?_s=usage",
});
assert.equal(usage.bankedResetCredits, 0);
const jsonCalls = calls.filter(
(call) => !call.url.includes("prod_mc_billing.ConsumerUiSvc/GetRemainingResets")
);
const resetCall = calls.find((call) =>
call.url.includes("prod_mc_billing.ConsumerUiSvc/GetRemainingResets")
);
assert.ok(resetCall);
assert.equal(resetCall.init.method, "POST");
assert.equal(
new Headers(resetCall.init.headers).get("content-type"),
"application/grpc-web+proto"
);
assert.equal(new Headers(resetCall.init.headers).get("x-grpc-web"), "1");
assert.equal(
new Headers(resetCall.init.headers).get("authorization"),
"Bearer fixture-access-token"
);
assert.deepEqual(
calls.map((call) => call.url),
jsonCalls.map((call) => call.url),
[
"https://cli-chat-proxy.grok.com/v1/user?include=subscription",
"https://cli-chat-proxy.grok.com/v1/billing?format=credits",
"https://cli-chat-proxy.grok.com/v1/auto-topup-rule",
]
);
for (const { init } of calls) {
for (const { init } of jsonCalls) {
assert.equal(init.method, "GET");
assert.equal(init.redirect, "error");
assert.equal(init.body, undefined);
@@ -212,8 +305,8 @@ test("grok-cli fetches the fixed read-only surfaces with the full Grok client pr
assert.ok(headers.get("x-grok-client-identifier"));
assert.equal(headers.get("x-grok-client-mode"), "headless");
}
assert.equal(new Headers(calls[0].init.headers).has("x-userid"), false);
assert.equal(new Headers(calls[2].init.headers).get("x-userid"), "canonical-user-id");
assert.equal(new Headers(jsonCalls[0].init.headers).has("x-userid"), false);
assert.equal(new Headers(jsonCalls[2].init.headers).get("x-userid"), "canonical-user-id");
assert.deepEqual(grokTesting.networkPolicy, {
method: "GET",
redirect: "error",
@@ -549,6 +642,39 @@ test("SuperGrokPro explicit null creditUsagePercent still yields a weekly quota
});
});
test("grok-cli surfaces bankedResetCredits when GetRemainingResets returns one token", async () => {
const fixtureFetch = successFixtures();
const usage = await getUsage((async (input: string | URL | Request) => {
const url = String(input);
if (url.includes("GetRemainingResets")) return oneResetTokenResponse();
return fixtureFetch(input);
}) as typeof fetch);
assert.equal(usage.bankedResetCredits, 1);
assert.ok(usage.quotas?.weekly);
});
test("grok-cli surfaces bankedResetCredits for live nested 10/20/30 tokens", async () => {
const fixtureFetch = successFixtures();
const usage = await getUsage((async (input: string | URL | Request) => {
const url = String(input);
if (url.includes("GetRemainingResets")) return liveResetTokenResponse();
return fixtureFetch(input);
}) as typeof fetch);
assert.equal(usage.bankedResetCredits, 1);
assert.ok(usage.quotas?.weekly);
});
test("grok-cli omits bankedResetCredits when GetRemainingResets fails (fail-open)", async () => {
const fixtureFetch = successFixtures();
const usage = await getUsage((async (input: string | URL | Request) => {
const url = String(input);
if (url.includes("GetRemainingResets")) return new Response("nope", { status: 404 });
return fixtureFetch(input);
}) as typeof fetch);
assert.equal("bankedResetCredits" in usage, false);
assert.ok(usage.quotas?.weekly);
});
test("SuperGrokPro omitted currentPeriod still yields a weekly bar with null resetAt", async () => {
const usage = await getUsage(
successFixtures({

View File

@@ -0,0 +1,195 @@
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-grok-reset-credits-"));
process.env.DATA_DIR = TEST_DATA_DIR;
process.env.API_KEY_SECRET = "test-grok-reset-credits-secret";
process.env.STORAGE_ENCRYPTION_KEY = "grok-reset-credits-test-key-32-bytes-min";
process.env.DISABLE_SQLITE_AUTO_BACKUP = "true";
const core = await import("../../src/lib/db/core.ts");
const providersDb = await import("../../src/lib/db/providers.ts");
const grokReset = await import("../../src/lib/usage/grokResetCredits.ts");
const originalFetch = globalThis.fetch;
const LIST_URL = "https://grok.com/prod_mc_billing.ConsumerUiSvc/GetRemainingResets";
const REDEEM_URL = "https://grok.com/prod_mc_billing.ConsumerUiSvc/RedeemReset";
const GRANTED = 1786560540;
const EXPIRES = 1789238940;
const TOKEN_ID = "test-token-id";
function encodeVarint(value: number): Buffer {
const bytes: number[] = [];
let v = BigInt(value);
do {
let byte = Number(v & 0x7fn);
v >>= 7n;
if (v !== 0n) byte |= 0x80;
bytes.push(byte);
} while (v !== 0n);
return Buffer.from(bytes);
}
function encodeTag(fieldNumber: number, wireType: number): Buffer {
return encodeVarint((fieldNumber << 3) | wireType);
}
function encodeLengthDelimited(fieldNumber: number, body: Buffer): Buffer {
return Buffer.concat([encodeTag(fieldNumber, 2), encodeVarint(body.length), body]);
}
function encodeVarintField(fieldNumber: number, value: number): Buffer {
return Buffer.concat([encodeTag(fieldNumber, 0), encodeVarint(value)]);
}
function grpcFrame(flag: number, payload: Buffer): Buffer {
const header = Buffer.alloc(5);
header[0] = flag;
header.writeUInt32BE(payload.length, 1);
return Buffer.concat([header, payload]);
}
function listResponse(tokens: Array<{ id: string; expires: number }>): Response {
const payload = Buffer.concat(
tokens.map((token) =>
encodeLengthDelimited(
10,
Buffer.concat([
encodeLengthDelimited(1, Buffer.from(token.id, "utf8")),
encodeVarintField(2, GRANTED),
encodeVarintField(3, token.expires),
])
)
)
);
const trailer = Buffer.from("grpc-status:0\r\n", "utf8");
return new Response(Buffer.concat([grpcFrame(0x00, payload), grpcFrame(0x80, trailer)]), {
status: 200,
headers: { "content-type": "application/grpc-web+proto" },
});
}
function trailerResponse(status: number, message?: string): Response {
const lines = [`grpc-status:${status}\r\n`];
if (message) lines.push(`grpc-message:${encodeURIComponent(message)}\r\n`);
const trailer = Buffer.from(lines.join(""), "utf8");
return new Response(Buffer.concat([grpcFrame(0x00, Buffer.alloc(0)), grpcFrame(0x80, trailer)]), {
status: 200,
headers: { "content-type": "application/grpc-web+proto" },
});
}
function usageJsonResponse(): Response {
return new Response(
JSON.stringify({
plan: "SuperGrok Heavy",
quotas: { weekly: { used: 0, total: 100, remainingPercentage: 100 } },
bankedResetCredits: 0,
}),
{ status: 200, headers: { "content-type": "application/json" } }
);
}
async function resetStorage() {
core.resetDbInstance();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
}
async function createGrokConnection(overrides: Record<string, unknown> = {}) {
return providersDb.createProviderConnection({
provider: "grok-cli",
authType: "oauth",
name: `Grok Reset ${Date.now()} ${Math.random()}`,
email: `grok-${Date.now()}-${Math.random()}@example.test`,
accessToken: "grok-access-token",
refreshToken: "grok-refresh-token",
...overrides,
});
}
test.beforeEach(async () => {
globalThis.fetch = originalFetch;
await resetStorage();
});
test.after(async () => {
globalThis.fetch = originalFetch;
core.resetDbInstance();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
});
test("listGrokResetCredits returns public rows without logging token ids in usage", async () => {
const connection = (await createGrokConnection()) as { id: string };
globalThis.fetch = async (url) => {
if (String(url) === LIST_URL) return listResponse([{ id: TOKEN_ID, expires: EXPIRES }]);
return new Response("unexpected", { status: 500 });
};
const result = await grokReset.listGrokResetCredits(connection.id);
assert.equal(result.availableCount, 1);
assert.equal(result.credits[0]?.selectionToken, TOKEN_ID);
assert.equal(result.credits[0]?.expiresAt, new Date(EXPIRES * 1000).toISOString());
});
test("consumeGrokResetCredit posts RedeemReset then refreshes usage", async () => {
const connection = (await createGrokConnection()) as { id: string };
const calls: string[] = [];
globalThis.fetch = async (url, init = {}) => {
calls.push(String(url));
if (String(url) === LIST_URL) return listResponse([{ id: TOKEN_ID, expires: EXPIRES }]);
if (String(url) === REDEEM_URL) {
const headers = init.headers as Record<string, string>;
assert.equal(headers.Authorization, ["Bearer", "grok-access-token"].join(" "));
return trailerResponse(0);
}
if (String(url).includes("/user?include=subscription")) {
return new Response(JSON.stringify({ userId: "u1", subscriptionTier: "SuperGrok Heavy" }), {
status: 200,
});
}
if (String(url).includes("/billing?format=credits")) {
return new Response(
JSON.stringify({
config: {
creditUsagePercent: 0,
currentPeriod: { type: "WEEKLY", end: "2026-09-12T00:00:00.000Z" },
},
}),
{ status: 200 }
);
}
if (String(url).includes("/auto-topup-rule")) {
return new Response(JSON.stringify({}), { status: 200 });
}
return usageJsonResponse();
};
const result = await grokReset.consumeGrokResetCredit(connection.id, "redeem-1", TOKEN_ID);
assert.equal(result.outcome, "reset");
assert.equal(calls.includes(REDEEM_URL), true);
assert.equal(typeof result.usage, "object");
});
test("consumeGrokResetCredit rejects non-grok connections", async () => {
const connection = (await providersDb.createProviderConnection({
provider: "codex",
authType: "oauth",
name: "Codex decoy",
email: `codex-${Date.now()}@example.test`,
accessToken: "codex-access-token",
refreshToken: "codex-refresh-token",
})) as { id: string };
await assert.rejects(
() => grokReset.consumeGrokResetCredit(connection.id, "redeem-wrong"),
(error: unknown) =>
error instanceof grokReset.GrokResetCreditError &&
error.status === 400 &&
error.code === "grok_provider_required"
);
});

View File

@@ -0,0 +1,191 @@
import test from "node:test";
import assert from "node:assert/strict";
import {
decodeGrokResetCreditsFrame,
encodeRedeemResetRequest,
} from "../../open-sse/services/grokResetCreditsFrame.ts";
const GRANTED = 1786560540;
const EXPIRES = 1789238940;
const TOKEN_ID = "test-token-id"; // 13 bytes
function encodeVarint(value: number): Buffer {
const bytes: number[] = [];
let v = BigInt(value);
do {
let byte = Number(v & 0x7fn);
v >>= 7n;
if (v !== 0n) byte |= 0x80;
bytes.push(byte);
} while (v !== 0n);
return Buffer.from(bytes);
}
function encodeTag(fieldNumber: number, wireType: number): Buffer {
return encodeVarint((fieldNumber << 3) | wireType);
}
function encodeLengthDelimited(fieldNumber: number, body: Buffer): Buffer {
return Buffer.concat([encodeTag(fieldNumber, 2), encodeVarint(body.length), body]);
}
function encodeVarintField(fieldNumber: number, value: number): Buffer {
return Buffer.concat([encodeTag(fieldNumber, 0), encodeVarint(value)]);
}
function encodeToken(id: string, granted: number, expires: number): Buffer {
return Buffer.concat([
encodeLengthDelimited(1, Buffer.from(id, "utf8")),
encodeVarintField(2, granted),
encodeVarintField(3, expires),
]);
}
/** google.protobuf.Timestamp with seconds only (nanos omitted). Live inner length is 6. */
function encodeTimestampSeconds(unixSeconds: number): Buffer {
return encodeVarintField(1, unixSeconds);
}
/**
* X500 2026-09-06 hotmail SuperGrokPro GetRemainingResets DATA:
* top field 10, nested fields 10/20/30 all length-delimited
* (id 13B, granted Timestamp 6B, expires Timestamp 6B).
*/
function encodeLiveToken(id: string, granted: number, expires: number): Buffer {
return Buffer.concat([
encodeLengthDelimited(10, Buffer.from(id, "utf8")),
encodeLengthDelimited(20, encodeTimestampSeconds(granted)),
encodeLengthDelimited(30, encodeTimestampSeconds(expires)),
]);
}
function frameData(payload: Buffer): Buffer {
const header = Buffer.alloc(5);
header[0] = 0x00;
header.writeUInt32BE(payload.length, 1);
return Buffer.concat([header, payload]);
}
function frameTrailer(statusText = "grpc-status:0\r\n"): Buffer {
const body = Buffer.from(statusText, "utf8");
const header = Buffer.alloc(5);
header[0] = 0x80;
header.writeUInt32BE(body.length, 1);
return Buffer.concat([header, body]);
}
test("empty DATA frame + grpc-status 0 is a real zero inventory", () => {
const buffer = Buffer.concat([frameData(Buffer.alloc(0)), frameTrailer()]);
const decoded = decodeGrokResetCreditsFrame(buffer);
assert.equal(decoded.ok, true);
if (!decoded.ok) return;
assert.equal(decoded.snapshot.count, 0);
assert.equal(decoded.snapshot.nextExpiresAt, null);
});
test("one unexpired field-10 token counts as 1", () => {
const payload = encodeLengthDelimited(10, encodeToken(TOKEN_ID, GRANTED, EXPIRES));
const decoded = decodeGrokResetCreditsFrame(Buffer.concat([frameData(payload), frameTrailer()]));
assert.equal(decoded.ok, true);
if (!decoded.ok) return;
assert.equal(decoded.snapshot.count, 1);
assert.equal(decoded.snapshot.nextExpiresAt, new Date(EXPIRES * 1000).toISOString());
assert.equal(decoded.tokens.length, 1);
assert.equal(decoded.tokens[0]?.tokenId, TOKEN_ID);
assert.equal(decoded.tokens[0]?.expiresAt, new Date(EXPIRES * 1000).toISOString());
});
test("repeated field-10 is not collapsed by a Map walker", () => {
const a = encodeLengthDelimited(10, encodeToken("test-token-aa", GRANTED, EXPIRES));
const b = encodeLengthDelimited(10, encodeToken("test-token-bb", GRANTED, EXPIRES + 86400));
const decoded = decodeGrokResetCreditsFrame(
Buffer.concat([frameData(Buffer.concat([a, b])), frameTrailer()])
);
assert.equal(decoded.ok, true);
if (!decoded.ok) return;
assert.equal(decoded.snapshot.count, 2);
assert.equal(decoded.snapshot.nextExpiresAt, new Date(EXPIRES * 1000).toISOString());
assert.deepEqual(
decoded.tokens.map((token) => token.tokenId),
["test-token-aa", "test-token-bb"]
);
});
test("expired tokens are dropped from the count", () => {
const expired = encodeLengthDelimited(10, encodeToken("test-token-ex", GRANTED, 1_700_000_000));
const live = encodeLengthDelimited(10, encodeToken(TOKEN_ID, GRANTED, EXPIRES));
const decoded = decodeGrokResetCreditsFrame(
Buffer.concat([frameData(Buffer.concat([expired, live])), frameTrailer()])
);
assert.equal(decoded.ok, true);
if (!decoded.ok) return;
assert.equal(decoded.snapshot.count, 1);
assert.equal(decoded.snapshot.nextExpiresAt, new Date(EXPIRES * 1000).toISOString());
});
test("nonzero grpc-status is not a zero inventory", () => {
const decoded = decodeGrokResetCreditsFrame(
Buffer.concat([frameData(Buffer.alloc(0)), frameTrailer("grpc-status:13\r\n")])
);
assert.equal(decoded.ok, false);
if (decoded.ok) return;
assert.equal(decoded.reason, "trailer-nonzero");
});
test("trailer-only buffer is not a zero inventory", () => {
const decoded = decodeGrokResetCreditsFrame(frameTrailer());
assert.equal(decoded.ok, false);
if (decoded.ok) return;
assert.equal(decoded.reason, "no-data-frame");
});
test("empty buffer is not a zero inventory", () => {
const decoded = decodeGrokResetCreditsFrame(Buffer.alloc(0));
assert.equal(decoded.ok, false);
if (decoded.ok) return;
assert.equal(decoded.reason, "empty-buffer");
});
test("13-byte token id is a string, not a nested protobuf message", () => {
const payload = encodeLengthDelimited(10, encodeToken(TOKEN_ID, GRANTED, EXPIRES));
const decoded = decodeGrokResetCreditsFrame(Buffer.concat([frameData(payload), frameTrailer()]));
assert.equal(decoded.ok, true);
if (!decoded.ok) return;
assert.equal(decoded.snapshot.count, 1);
assert.equal(decoded.tokens[0]?.tokenId, TOKEN_ID);
assert.equal(decoded.tokens[0]?.tokenId.length, 13);
});
test("live nested fields 10/20/30 are not malformed", () => {
const liveInner = encodeLiveToken(TOKEN_ID, GRANTED, EXPIRES);
assert.equal(encodeTimestampSeconds(GRANTED).length, 6);
assert.equal(encodeTimestampSeconds(EXPIRES).length, 6);
const payload = encodeLengthDelimited(10, liveInner);
const decoded = decodeGrokResetCreditsFrame(Buffer.concat([frameData(payload), frameTrailer()]));
assert.equal(decoded.ok, true);
if (!decoded.ok) return;
assert.equal(decoded.snapshot.count, 1);
assert.equal(decoded.tokens[0]?.tokenId, TOKEN_ID);
assert.equal(decoded.tokens[0]?.expiresAt, new Date(EXPIRES * 1000).toISOString());
});
test("live nested field-30 expiry still drops expired cards", () => {
const expired = encodeLengthDelimited(10, encodeLiveToken("test-token-ex", GRANTED, 1_700_000_000));
const live = encodeLengthDelimited(10, encodeLiveToken(TOKEN_ID, GRANTED, EXPIRES));
const decoded = decodeGrokResetCreditsFrame(
Buffer.concat([frameData(Buffer.concat([expired, live])), frameTrailer()])
);
assert.equal(decoded.ok, true);
if (!decoded.ok) return;
assert.equal(decoded.snapshot.count, 1);
assert.equal(decoded.tokens[0]?.tokenId, TOKEN_ID);
});
test("RedeemReset request encodes token_id as protobuf field 10", () => {
const encoded = encodeRedeemResetRequest(TOKEN_ID);
const tag = encoded[0];
const length = encoded[1];
assert.equal(tag, (10 << 3) | 2);
assert.equal(length, TOKEN_ID.length);
assert.equal(encoded.subarray(2).toString("utf8"), TOKEN_ID);
});

View File

@@ -0,0 +1,176 @@
import test from "node:test";
import assert from "node:assert/strict";
import {
consumeGrokResetCredit,
listGrokResetCreditTokens,
mapGrokRedeemGrpcStatus,
} from "../../open-sse/services/grokResetCredits.ts";
import { encodeRedeemResetRequest } from "../../open-sse/services/grokResetCreditsFrame.ts";
const GRANTED = 1786560540;
const EXPIRES = 1789238940;
const TOKEN_ID = "test-token-id";
const REDEEM_URL = "https://grok.com/prod_mc_billing.ConsumerUiSvc/RedeemReset";
const LIST_URL = "https://grok.com/prod_mc_billing.ConsumerUiSvc/GetRemainingResets";
function encodeVarint(value: number): Buffer {
const bytes: number[] = [];
let v = BigInt(value);
do {
let byte = Number(v & 0x7fn);
v >>= 7n;
if (v !== 0n) byte |= 0x80;
bytes.push(byte);
} while (v !== 0n);
return Buffer.from(bytes);
}
function encodeTag(fieldNumber: number, wireType: number): Buffer {
return encodeVarint((fieldNumber << 3) | wireType);
}
function encodeLengthDelimited(fieldNumber: number, body: Buffer): Buffer {
return Buffer.concat([encodeTag(fieldNumber, 2), encodeVarint(body.length), body]);
}
function encodeVarintField(fieldNumber: number, value: number): Buffer {
return Buffer.concat([encodeTag(fieldNumber, 0), encodeVarint(value)]);
}
function grpcFrame(flag: number, payload: Buffer): Buffer {
const header = Buffer.alloc(5);
header[0] = flag;
header.writeUInt32BE(payload.length, 1);
return Buffer.concat([header, payload]);
}
function trailerResponse(status: number, message?: string): Response {
const lines = [`grpc-status:${status}\r\n`];
if (message) lines.push(`grpc-message:${encodeURIComponent(message)}\r\n`);
const trailer = Buffer.from(lines.join(""), "utf8");
return new Response(Buffer.concat([grpcFrame(0x00, Buffer.alloc(0)), grpcFrame(0x80, trailer)]), {
status: 200,
headers: { "content-type": "application/grpc-web+proto" },
});
}
function listResponse(tokens: Array<{ id: string; expires: number }>): Response {
const payload = Buffer.concat(
tokens.map((token) =>
encodeLengthDelimited(
10,
Buffer.concat([
encodeLengthDelimited(1, Buffer.from(token.id, "utf8")),
encodeVarintField(2, GRANTED),
encodeVarintField(3, token.expires),
])
)
)
);
const trailer = Buffer.from("grpc-status:0\r\n", "utf8");
return new Response(Buffer.concat([grpcFrame(0x00, payload), grpcFrame(0x80, trailer)]), {
status: 200,
headers: { "content-type": "application/grpc-web+proto" },
});
}
test("mapGrokRedeemGrpcStatus treats grpc 0 as reset", () => {
assert.equal(mapGrokRedeemGrpcStatus("0", null), "reset");
});
test("mapGrokRedeemGrpcStatus treats missing token as noCredit", () => {
assert.equal(
mapGrokRedeemGrpcStatus("9", "The token cannot be redeemed: it does not exist or is expired"),
"noCredit"
);
});
test("mapGrokRedeemGrpcStatus treats already-redeemed as alreadyRedeemed", () => {
assert.equal(mapGrokRedeemGrpcStatus("9", "token already redeemed"), "alreadyRedeemed");
});
test("mapGrokRedeemGrpcStatus treats invalid token_id as noCredit", () => {
assert.equal(mapGrokRedeemGrpcStatus("3", "redeem_reset(), Invalid token_id"), "noCredit");
});
test("listGrokResetCreditTokens returns public rows ordered by expiry", async () => {
const listed = await listGrokResetCreditTokens("fixture-access-token", async (url) => {
assert.equal(String(url), LIST_URL);
return listResponse([
{ id: "test-token-bb", expires: EXPIRES + 86400 },
{ id: "test-token-aa", expires: EXPIRES },
]);
});
assert.equal(listed.availableCount, 2);
assert.deepEqual(
listed.credits.map((credit) => credit.selectionToken),
["test-token-aa", "test-token-bb"]
);
assert.equal(listed.credits[0]?.expiresAt, new Date(EXPIRES * 1000).toISOString());
});
test("consumeGrokResetCredit posts RedeemReset with protobuf field 10 and skips inventory when tokenId is given", async () => {
const calls: Array<{ url: string; init: RequestInit }> = [];
const outcome = await consumeGrokResetCredit(
"fixture-access-token",
{ tokenId: TOKEN_ID },
async (url, init = {}) => {
calls.push({ url: String(url), init });
if (String(url) === LIST_URL) return listResponse([{ id: TOKEN_ID, expires: EXPIRES }]);
return trailerResponse(0);
}
);
assert.equal(outcome, "reset");
assert.equal(
calls.some((call) => call.url === LIST_URL),
false
);
const redeem = calls.find((call) => call.url === REDEEM_URL);
assert.ok(redeem);
assert.equal(redeem?.init.method, "POST");
const body = Buffer.from(redeem?.init.body as Buffer);
const payload = body.subarray(5);
assert.deepEqual(payload, encodeRedeemResetRequest(TOKEN_ID));
const headers = redeem?.init.headers as Record<string, string>;
assert.equal(headers.Authorization, ["Bearer", "fixture-access-token"].join(" "));
});
test("consumeGrokResetCredit picks the token that expires first when none is selected", async () => {
const calls: Array<{ url: string; body: Buffer | null }> = [];
const outcome = await consumeGrokResetCredit("fixture-access-token", {}, async (url, init = {}) => {
const body = init.body ? Buffer.from(init.body as Buffer) : null;
calls.push({ url: String(url), body });
if (String(url) === LIST_URL) {
return listResponse([
{ id: "test-token-bb", expires: EXPIRES + 86400 },
{ id: "test-token-aa", expires: EXPIRES },
]);
}
return trailerResponse(0);
});
assert.equal(outcome, "reset");
const redeem = calls.find((call) => call.url === REDEEM_URL);
assert.ok(redeem?.body);
const payload = redeem!.body!.subarray(5);
assert.deepEqual(payload, encodeRedeemResetRequest("test-token-aa"));
});
test("consumeGrokResetCredit maps a missing selected token via RedeemReset grpc-status 9", async () => {
const { GrokResetCreditError } = await import("../../open-sse/services/grokResetCredits.ts");
await assert.rejects(
() =>
consumeGrokResetCredit(
"fixture-access-token",
{ tokenId: "missing-token" },
async (url) => {
if (String(url) === LIST_URL) return listResponse([{ id: TOKEN_ID, expires: EXPIRES }]);
return trailerResponse(
9,
"The token cannot be redeemed: it does not exist or is expired"
);
}
),
(error: unknown) =>
error instanceof GrokResetCreditError && error.status === 409 && error.code === "no_credit"
);
});

View File

@@ -425,3 +425,38 @@ test("provider quota auto-refresh settings are accepted by the settings schema",
assert.equal(result.success, true);
});
test("grok-cli banked reset credits parse as an integer reset-credit counter including zero", () => {
const parsed = providerLimitUtils.parseQuotaData("grok-cli", {
quotas: {
weekly: { used: 37.25, total: 100, remainingPercentage: 62.75, isPercentageOnly: true },
},
bankedResetCredits: 0,
}) as ParsedQuota[];
const resetCredits = parsed.find((quota) => quota.name === "banked_reset_credits");
assert.ok(resetCredits);
assert.equal(resetCredits.isResetCredits, true);
assert.equal(resetCredits.creditCount, 0);
});
test("grok-cli omits the reset-credit row when bankedResetCredits is absent", () => {
const parsed = providerLimitUtils.parseQuotaData("grok-cli", {
quotas: {
weekly: { used: 37.25, total: 100, remainingPercentage: 62.75 },
},
}) as ParsedQuota[];
assert.equal(
parsed.some((quota) => quota.name === "banked_reset_credits"),
false
);
});
test("grok-cli exposes the redeem button when banked reset credits are present", () => {
const parsed = providerLimitUtils.parseQuotaData("grok-cli", {
quotas: { weekly: { used: 0, total: 100, remainingPercentage: 100 } },
bankedResetCredits: 2,
});
assert.equal(providerLimitUtils.computeCanRedeemResetCredit("grok-cli", parsed), true);
assert.equal(providerLimitUtils.computeCanRedeemResetCredit("codex", parsed), true);
assert.equal(providerLimitUtils.computeCanRedeemResetCredit("claude", parsed), false);
});