mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-05 16:04:43 +00:00
fix(usage): derive window names and unify pin selection (#5903)
* fix(usage): derive window names and unify pin selection Quota slots do not identify a period. Derive numeric windows and IDs from reported duration and quota scope; keep unknown lengths neutral. Resolve source defaults and explicit pins through one model, with a persisted empty selection distinct from defaults. * fix(plugins): declare the duration helper host requirement * fix(usage): verify persisted selections at the storage boundary
This commit is contained in:
@@ -326,3 +326,46 @@ it.each([401, 403])("reports an existing login rejected with HTTP %i", async (st
|
||||
else process.env["GROK_TOKEN"] = previous;
|
||||
}
|
||||
});
|
||||
|
||||
it.each([undefined, "USAGE_PERIOD_TYPE_DAILY", "USAGE_PERIOD_TYPE_UNKNOWN_WEEKLY"])(
|
||||
"does not invent a monthly period for %s",
|
||||
async (type) => {
|
||||
const directory = mkdtempSync(join(tmpdir(), "grok-period-"));
|
||||
try {
|
||||
const locator = join(directory, "auth.json");
|
||||
writeFileSync(locator, JSON.stringify({ access_token: "fixture" }));
|
||||
const report = await fetchUsage({ store: "file", locator }, async () =>
|
||||
Response.json({ config: { creditUsagePercent: 11, currentPeriod: { type } } }),
|
||||
);
|
||||
expect(report).toMatchObject({
|
||||
status: "available",
|
||||
windows: [
|
||||
{
|
||||
id: type ? `period:${type}` : "period:unknown",
|
||||
label: type ?? "Current period",
|
||||
shortLabel: "",
|
||||
},
|
||||
],
|
||||
});
|
||||
} finally {
|
||||
rmSync(directory, { recursive: true, force: true });
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it("does not call credits monthly when no monthly limit was reported", async () => {
|
||||
const directory = mkdtempSync(join(tmpdir(), "grok-credits-"));
|
||||
try {
|
||||
const locator = join(directory, "auth.json");
|
||||
writeFileSync(locator, JSON.stringify({ access_token: "fixture" }));
|
||||
const report = await fetchUsage({ store: "file", locator }, async () =>
|
||||
Response.json({ config: { used: { val: 11 } } }),
|
||||
);
|
||||
expect(report).toMatchObject({
|
||||
status: "available",
|
||||
balances: [{ id: "credits", label: "Credits", used: 11 }],
|
||||
});
|
||||
} finally {
|
||||
rmSync(directory, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -74,15 +74,14 @@ export function extractGrokTokenFromAuth(auth: unknown): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
function grokMonthlyCreditBalance(
|
||||
response: z.infer<typeof GrokUsageResponseSchema>,
|
||||
): UsageBalance | null {
|
||||
function grokCreditBalance(response: z.infer<typeof GrokUsageResponseSchema>): UsageBalance | null {
|
||||
const limit = response.config?.monthlyLimit?.val ?? null;
|
||||
const used = response.config?.used?.val ?? response.usage?.creditUsage ?? null;
|
||||
if (limit === null && used === null) return null;
|
||||
return {
|
||||
id: "monthly_credits",
|
||||
label: "Monthly credits",
|
||||
// Only the named monthly allowance establishes a monthly credit bucket.
|
||||
id: limit === null ? "credits" : "monthly_credits",
|
||||
label: limit === null ? "Credits" : "Monthly credits",
|
||||
used,
|
||||
remaining: limit !== null && used !== null ? Math.max(0, limit - used) : null,
|
||||
limit,
|
||||
@@ -95,11 +94,18 @@ function grokUsageWindow(response: z.infer<typeof GrokUsageResponseSchema>): Usa
|
||||
const percent = response.config?.creditUsagePercent;
|
||||
if (typeof percent !== "number") return null;
|
||||
const period = response.config?.currentPeriod;
|
||||
const weekly = (period?.type ?? "").toUpperCase().includes("WEEKLY");
|
||||
const names = {
|
||||
USAGE_PERIOD_TYPE_WEEKLY: { id: "weekly", label: "Weekly", shortLabel: "wk" },
|
||||
USAGE_PERIOD_TYPE_MONTHLY: { id: "monthly", label: "Monthly", shortLabel: "mo" },
|
||||
};
|
||||
// An absent or unfamiliar enum does not establish a monthly duration.
|
||||
const name = names[period?.type as keyof typeof names] ?? {
|
||||
id: `period:${period?.type || "unknown"}`,
|
||||
label: period?.type || "Current period",
|
||||
shortLabel: "",
|
||||
};
|
||||
return windowFromUsedPct({
|
||||
id: weekly ? "weekly" : "monthly",
|
||||
label: weekly ? "Weekly" : "Monthly",
|
||||
shortLabel: weekly ? "wk" : "mo",
|
||||
...name,
|
||||
utilizationPct: percent,
|
||||
resetsAt: period?.end ?? null,
|
||||
tone: toneFromUsedPct(percent),
|
||||
@@ -129,7 +135,7 @@ export async function fetchUsage(
|
||||
if (!res.ok) throw new Error(`Grok usage API returned ${res.status}`);
|
||||
|
||||
const resp = GrokUsageResponseSchema.parse(await res.json());
|
||||
const balance = grokMonthlyCreditBalance(resp);
|
||||
const balance = grokCreditBalance(resp);
|
||||
const window = grokUsageWindow(resp);
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user