fix(server): show Claude usage when a quota window has no scheduled reset (#1855)
The Anthropic usage API returns resets_at: null when a window has no active session. The schema only allowed string/undefined, so the parse threw and the whole Claude provider surfaced as an error in the quota panel. The consuming code already handled null; only the schema was stricter than the API.
This commit is contained in:
@@ -37,7 +37,7 @@ const ClaudeCredentialsSchema = z.object({
|
|||||||
|
|
||||||
const ClaudeUsageWindowSchema = z.object({
|
const ClaudeUsageWindowSchema = z.object({
|
||||||
utilization: ApiNumberSchema,
|
utilization: ApiNumberSchema,
|
||||||
resets_at: z.string().optional(),
|
resets_at: z.string().nullish(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const ClaudeUsageResponseSchema = z.object({
|
const ClaudeUsageResponseSchema = z.object({
|
||||||
|
|||||||
@@ -434,6 +434,33 @@ describe("real provider usage fetchers", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts a null Claude resets_at when a window has no scheduled reset", async () => {
|
||||||
|
writeClaudeCredentials(claudeHome, "at_valid");
|
||||||
|
fetchApi = mockFetch(
|
||||||
|
new Map([
|
||||||
|
[
|
||||||
|
"https://api.anthropic.com/api/oauth/usage",
|
||||||
|
() =>
|
||||||
|
jsonResponse({
|
||||||
|
five_hour: { utilization: 0, resets_at: null },
|
||||||
|
seven_day: { utilization: 1, resets_at: "2026-06-04T00:00:00Z" },
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const result = await service().listUsage();
|
||||||
|
const claude = findProvider(result, "claude");
|
||||||
|
|
||||||
|
expect(claude).toMatchObject({
|
||||||
|
status: "available",
|
||||||
|
windows: expect.arrayContaining([
|
||||||
|
expect.objectContaining({ id: "five_hour", usedPct: 0, resetsAt: null }),
|
||||||
|
expect.objectContaining({ id: "weekly", usedPct: 1 }),
|
||||||
|
]),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("returns unavailable Claude usage when credentials are missing", async () => {
|
it("returns unavailable Claude usage when credentials are missing", async () => {
|
||||||
fetchApi = vi.fn() as never;
|
fetchApi = vi.fn() as never;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user