Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions apps/server/src/provider/GrokProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,63 @@ it.layer(NodeServices.layer)("checkGrokProviderStatus", (it) => {

describe("Grok usage limits", () => {
const checkedAt = "2026-09-16T00:00:00.000Z";
const weeklyPeriod = {
type: "USAGE_PERIOD_TYPE_WEEKLY",
start: "2026-09-11T03:10:30.159171+00:00",
end: "2026-09-18T03:10:30.159171+00:00",
};

it("shows zero usage for complete weekly and monthly periods with no percentage", () => {
for (const [currentPeriod, kind, label, resetsAt] of [
[weeklyPeriod, "weekly", "Weekly", "2026-09-18T03:10:30.159Z"],
[
{
type: "USAGE_PERIOD_TYPE_MONTHLY",
start: "2026-09-01T00:00:00.000Z",
end: "2026-10-01T00:00:00.000Z",
},
"monthly",
"Monthly",
"2026-10-01T00:00:00.000Z",
],
] as const) {
const response = { config: { currentPeriod } };
expect
.soft(grokUsageResponseToLimits(response, checkedAt).windows)
.toEqual([{ id: "subscription", kind, label, usedPercent: 0, resetsAt }]);
}
});

it("keeps incomplete, invalid, unordered, and unknown periods unreported", () => {
for (const currentPeriod of [
undefined,
{ ...weeklyPeriod, type: undefined },
{ ...weeklyPeriod, type: "USAGE_PERIOD_TYPE_DAILY" },
{ ...weeklyPeriod, start: undefined },
{ ...weeklyPeriod, end: undefined },
{ ...weeklyPeriod, start: "invalid" },
{ ...weeklyPeriod, end: "invalid" },
{ ...weeklyPeriod, start: weeklyPeriod.end },
{ ...weeklyPeriod, start: weeklyPeriod.end, end: weeklyPeriod.start },
]) {
const response = { config: { currentPeriod } };
expect
.soft(grokUsageResponseToLimits(response, checkedAt).windows, JSON.stringify(response))
.toEqual([]);
}
});

it("rejects impossible calendar dates at either period boundary", () => {
for (const [start, end] of [
["2026-02-30T00:00:00.000Z", "2026-03-09T00:00:00.000Z"],
["2026-02-23T00:00:00.000Z", "2026-02-30T00:00:00.000Z"],
]) {
const response = { config: { currentPeriod: { ...weeklyPeriod, start, end } } };
expect
.soft(grokUsageResponseToLimits(response, checkedAt).windows, JSON.stringify(response))
.toEqual([]);
}
});

it("uses the reported subscription percentage and weekly reset", () => {
const limits = grokUsageResponseToLimits(
Expand Down Expand Up @@ -665,6 +722,50 @@ it.layer(NodeServices.layer)("readGrokAccount", (it) => {
),
);

it.effect("ignores malformed period starts without inventing usage", () =>
Effect.gen(function* () {
for (const start of [null, 42]) {
for (const creditUsagePercent of [37.5, undefined]) {
const response = {
config: {
creditUsagePercent,
currentPeriod: {
type: "USAGE_PERIOD_TYPE_WEEKLY",
start,
end: "2026-09-18T03:10:30.159171+00:00",
},
},
};
const { usageLimits } = yield* readGrokAccount({
HOME: "/definitely/not/a/grok-home",
GROK_AUTH: '{"https://accounts.x.ai/sign-in":{"key":"session-token"}}',
}).pipe(
Effect.provideService(
HttpClient.HttpClient,
HttpClient.make((request) =>
Effect.succeed(HttpClientResponse.fromWeb(request, Response.json(response))),
),
),
);
expect.soft(usageLimits.unavailable, JSON.stringify(response)).toBeUndefined();
expect.soft(usageLimits.windows, JSON.stringify(response)).toEqual(
creditUsagePercent === undefined
? []
: [
{
id: "subscription",
kind: "weekly",
label: "Weekly",
usedPercent: creditUsagePercent,
resetsAt: "2026-09-18T03:10:30.159Z",
},
],
);
}
}
}),
);

it.effect("does not use unrelated scopes, API keys, or custom auth deployments", () =>
Effect.gen(function* () {
for (const environment of [
Expand Down
43 changes: 35 additions & 8 deletions packages/provider-grok/src/server/usageLimits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,55 @@ const GrokUsageResponse = Schema.Struct({
currentPeriod: Schema.optional(
Schema.Struct({
type: Schema.optional(Schema.String),
start: Schema.optional(Schema.Unknown),
end: Schema.optional(Schema.String),
}),
),
}),
),
});

function parsePeriodBoundary(value: string | undefined) {
if (
!value ||
value !== value.trim() ||
!/^(?:\d{4}|[+-]\d{6})-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?|24:00(?::00(?:\.0+)?)?)(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(
value,
)
) {
return Number.NaN;
}
// Date parsing can normalize impossible calendar dates instead of rejecting them.
const datePart = value.slice(0, value.indexOf("T"));
const date = DateTime.make(`${datePart}T00:00:00.000Z`);
if (Option.isNone(date)) return Number.NaN;
const parts = DateTime.toPartsUtc(date.value);
if (parts.month !== Number(datePart.slice(-5, -3)) || parts.day !== Number(datePart.slice(-2))) {
return Number.NaN;
}
return Date.parse(value);
}

export function grokUsageResponseToLimits(
response: typeof GrokUsageResponse.Type,
checkedAt: string,
) {
const usedPercent = response.config?.creditUsagePercent;
if (usedPercent === undefined || !Number.isFinite(usedPercent)) {
// A billing read that succeeded but carries no percentage is an account
// with nothing metered yet, not one that can never report: xAI omits the
// field entirely (rather than sending 0) until usage registers, then fills
// it in.
return makeUsageLimits({ checkedAt, windows: [] });
}
const period = response.config?.currentPeriod;
const periodType = period?.type?.replace(/^USAGE_PERIOD_TYPE_/, "");
const kind = periodType === "WEEKLY" ? "weekly" : periodType === "MONTHLY" ? "monthly" : "other";
let usedPercent = response.config?.creditUsagePercent;
if (
usedPercent === undefined &&
(kind === "weekly" || kind === "monthly") &&
typeof period?.start === "string" &&
parsePeriodBoundary(period?.start) < parsePeriodBoundary(period?.end)
) {
// Grok omits a zero percentage while retaining the complete subscription period.
usedPercent = 0;
}
if (usedPercent === undefined || !Number.isFinite(usedPercent)) {
return makeUsageLimits({ checkedAt, windows: [] });
}
const reset = period?.end ? DateTime.make(period.end) : Option.none();
const window: ServerProviderUsageWindow = {
id: "subscription",
Expand Down
Loading