feat(billing): implement G1 AI credits overage flow with billing telemetry (#18590)

This commit is contained in:
Gaurav
2026-02-27 10:15:06 -08:00
committed by GitHub
parent fdd844b405
commit b2d6844f9b
55 changed files with 3182 additions and 23 deletions

View File

@@ -19,17 +19,24 @@ import { getErrorStatus, ModelNotFoundError } from './httpErrors.js';
*/
export class TerminalQuotaError extends Error {
retryDelayMs?: number;
reason?: string;
constructor(
message: string,
override readonly cause: GoogleApiError,
retryDelaySeconds?: number,
reason?: string,
) {
super(message);
this.name = 'TerminalQuotaError';
this.retryDelayMs = retryDelaySeconds
? retryDelaySeconds * 1000
: undefined;
this.reason = reason;
}
get isInsufficientCredits(): boolean {
return this.reason === 'INSUFFICIENT_G1_CREDITS_BALANCE';
}
}
@@ -121,6 +128,7 @@ function classifyValidationRequiredError(
}
if (
!errorInfo.domain ||
!CLOUDCODE_DOMAINS.includes(errorInfo.domain) ||
errorInfo.reason !== 'VALIDATION_REQUIRED'
) {
@@ -293,6 +301,16 @@ export function classifyGoogleError(error: unknown): unknown {
}
if (errorInfo) {
// INSUFFICIENT_G1_CREDITS_BALANCE is always terminal, regardless of domain
if (errorInfo.reason === 'INSUFFICIENT_G1_CREDITS_BALANCE') {
return new TerminalQuotaError(
`${googleApiError.message}`,
googleApiError,
delaySeconds,
errorInfo.reason,
);
}
// New Cloud Code API quota handling
if (errorInfo.domain) {
const validDomains = [
@@ -313,6 +331,7 @@ export function classifyGoogleError(error: unknown): unknown {
`${googleApiError.message}`,
googleApiError,
delaySeconds,
errorInfo.reason,
);
}
}