fix: scope quota reports to authorized subscription accounts

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Devin FoleyandPaperclip committed 2026-10-06 11:28:22 -07:00
1 parent a85fa3af31
commit e85b02f99e
24 files changed
+1983 -182

No files matched your search

@@ -1,3 +1,4 @@
import { quotaUnavailableMessage } from "@/lib/quota-refresh";
import type { QuotaWindow } from "@paperclipai/shared";
import { cn, quotaSourceDisplayName } from "@/lib/utils";
@@ -66,7 +67,7 @@ export function ClaudeSubscriptionPanel({
Anthropic subscription
</div>
<div className="mt-1 text-sm text-muted-foreground">
Live Claude quota windows.
Quota from the Claude subscription connected to this server.
</div>
</div>
{source ? (
@@ -77,8 +78,8 @@ export function ClaudeSubscriptionPanel({
</div>
{error ? (
<div className="mt-4 border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive">
{error}
<div role="status" className="mt-4 text-sm text-muted-foreground">
{quotaUnavailableMessage(windows.length > 0)}
</div>
) : null}
+4 -3
View File
@@ -1,3 +1,4 @@
import { quotaUnavailableMessage } from "@/lib/quota-refresh";
import type { QuotaWindow } from "@paperclipai/shared";
import { cn, quotaSourceDisplayName } from "@/lib/utils";
@@ -69,7 +70,7 @@ export function CodexSubscriptionPanel({
Codex subscription
</div>
<div className="mt-1 text-sm text-muted-foreground">
Live Codex quota windows.
Quota from the Codex subscription connected to this server.
</div>
</div>
{source ? (
@@ -80,8 +81,8 @@ export function CodexSubscriptionPanel({
</div>
{error ? (
<div className="mt-4 border border-destructive/40 bg-destructive/10 px-3 py-2 text-sm text-destructive">
{error}
<div role="status" className="mt-4 text-sm text-muted-foreground">
{quotaUnavailableMessage(windows.length > 0)}
</div>
) : null}
+30
View File
@@ -0,0 +1,30 @@
import type { ProviderQuotaResult } from "@paperclipai/shared";
const invalidCredentials = new Set([
"credentials_unavailable",
"authentication_required",
"refresh_token_reused",
"refresh_token_expired",
"refresh_token_invalidated",
]);
/** Keep last successful windows through transient failures, never revoked auth. */
export function retainQuotaWindows(
previous: ProviderQuotaResult[] | undefined,
incoming: ProviderQuotaResult[],
): ProviderQuotaResult[] {
return incoming.map((result) => {
if (result.ok || (result.errorFamily && invalidCredentials.has(result.errorFamily))) return result;
const last = previous?.find((entry) => entry.provider === result.provider && entry.accountKey === result.accountKey);
return last?.windows.length
? { ...result, windows: last.windows, source: last.source, capturedAt: last.capturedAt }
: result;
});
}
// Never render adapter diagnostics, even when talking to an older server.
export function quotaUnavailableMessage(hasPreviousWindows: boolean): string {
return hasPreviousWindows
? "Showing the last available quota. Updates will resume automatically."
: "Subscription quota is currently unavailable. Check usage with your provider.";
}