Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
87 changes: 87 additions & 0 deletions packages/provider-grok/src/server/usage.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from "@effect/vitest";

import { GROK_COST_USD_TICKS_PER_DOLLAR, parseGrokLine } from "./usage.ts";
import { grokUsageResponseToLimits } from "./usageLimits.ts";

describe("parseGrokLine", () => {
/** Shaped after a real Grok Build `turn_completed` session update. */
Expand Down Expand Up @@ -314,3 +315,89 @@ describe("parseGrokLine", () => {
expect(records[0]?.timestampMs).toBe(1_786_372_566_000);
});
});

describe("Grok usage limits", () => {
const checkedAt = "2026-09-16T00:00:00.000Z";

it("treats an omitted percentage as zero only for a complete known billing period", () => {
expect(
grokUsageResponseToLimits(
{
config: {
currentPeriod: {
type: "USAGE_PERIOD_TYPE_WEEKLY",
start: "2026-09-11T03:10:30.159171+00:00",
end: "2026-09-18T03:10:30.159171+00:00",
},
},
},
checkedAt,
).windows,
).toEqual([
{
id: "subscription",
kind: "weekly",
label: "Weekly",
usedPercent: 0,
resetsAt: "2026-09-18T03:10:30.159Z",
},
]);

expect(
grokUsageResponseToLimits(
{
config: {
currentPeriod: {
type: "USAGE_PERIOD_TYPE_MONTHLY",
start: "2026-09-01T00:00:00.000Z",
end: "2026-10-01T00:00:00.000Z",
},
},
},
checkedAt,
).windows,
).toEqual([
{
id: "subscription",
kind: "monthly",
label: "Monthly",
usedPercent: 0,
resetsAt: "2026-10-01T00:00:00.000Z",
},
]);

for (const currentPeriod of [
{ type: "USAGE_PERIOD_TYPE_WEEKLY", end: "2026-09-18T03:10:30.159171+00:00" },
{ type: "USAGE_PERIOD_TYPE_WEEKLY", start: "2026-09-11T03:10:30.159171+00:00" },
{
type: "USAGE_PERIOD_TYPE_WEEKLY",
start: "invalid",
end: "2026-09-18T03:10:30.159171+00:00",
},
{
type: "USAGE_PERIOD_TYPE_WEEKLY",
start: "2026-09-18T03:10:30.159171+00:00",
end: "2026-09-11T03:10:30.159171+00:00",
},
{
type: "USAGE_PERIOD_TYPE_WEEKLY",
start: "2026-09-11T03:10:30.159171+00:00",
end: "invalid",
},
{
type: "USAGE_PERIOD_TYPE_WEEKLY",
start: "2026-09-11T03:10:30.159171+00:00",
end: "2026-09-11T03:10:30.159171+00:00",
},
{
type: "USAGE_PERIOD_TYPE_DAILY",
start: "2026-09-11T03:10:30.159171+00:00",
end: "2026-09-18T03:10:30.159171+00:00",
},
]) {
expect(grokUsageResponseToLimits({ config: { currentPeriod } }, checkedAt).windows).toEqual(
[],
);
}
});
});
28 changes: 16 additions & 12 deletions packages/provider-grok/src/server/usageLimits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const GrokUsageResponse = Schema.Struct({
currentPeriod: Schema.optional(
Schema.Struct({
type: Schema.optional(Schema.String),
start: Schema.optional(Schema.String),
end: Schema.optional(Schema.String),
}),
),
Expand All @@ -42,22 +43,25 @@ 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. Calling that `unsupported` would strand the account — the Limits
// view drops unsupported entries and deliberately mutes their notice, so a
// freshly signed-in Grok account would vanish with no explanation until it
// happened to be used, and `applyUsageLimitsUpdate` would refuse the
// mid-turn windows that could have recovered it.
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";
const start = period?.start ? DateTime.make(period.start) : Option.none();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
const reset = period?.end ? DateTime.make(period.end) : Option.none();
const completeKnownPeriod =
(kind === "weekly" || kind === "monthly") &&
Option.isSome(start) &&
Option.isSome(reset) &&
DateTime.toEpochMillis(start.value) < DateTime.toEpochMillis(reset.value);
// Observed billing responses omit a zero percentage while retaining a
// complete subscription period; the Grok CLI shows that same period as 0%.
// An incomplete or unknown response remains unreported.
const usedPercent = response.config?.creditUsagePercent ?? (completeKnownPeriod ? 0 : undefined);
if (usedPercent === undefined || !Number.isFinite(usedPercent)) {
// Keep an incomplete successful response visible and retryable. Marking it
// unsupported would drop the account from the Limits view permanently.
return makeUsageLimits({ checkedAt, windows: [] });
}
const window: ServerProviderUsageWindow = {
id: "subscription",
kind,
Expand Down
Loading