diff --git a/src/hooks/runtime-fallback/auto-retry-signal.test.ts b/src/hooks/runtime-fallback/auto-retry-signal.test.ts index e734b309b..e485fbd6c 100644 --- a/src/hooks/runtime-fallback/auto-retry-signal.test.ts +++ b/src/hooks/runtime-fallback/auto-retry-signal.test.ts @@ -15,6 +15,7 @@ describe("extractAutoRetrySignal", () => { //#then expect(signal).toBeDefined() expect(signal?.signal).toContain("exceeded") + expect(signal?.signal).toContain("usage quota") }) test("detects standard 'quota exceeded' signal", () => { diff --git a/src/hooks/runtime-fallback/constants.ts b/src/hooks/runtime-fallback/constants.ts index e835b4099..f407ffea0 100644 --- a/src/hooks/runtime-fallback/constants.ts +++ b/src/hooks/runtime-fallback/constants.ts @@ -28,7 +28,7 @@ export const RETRYABLE_ERROR_PATTERNS = [ /quota\s+will\s+reset\s+after/i, /quota.?exceeded/i, /exceeded.*quota/i, - /usage.?quota/i, + /usage\s*quota/i, /exhausted\s+your\s+capacity/i, /all\s+credentials\s+for\s+model/i, /cool(?:ing)?\s+down/i, diff --git a/src/hooks/runtime-fallback/error-classifier.ts b/src/hooks/runtime-fallback/error-classifier.ts index 614023f1c..3bb46454c 100644 --- a/src/hooks/runtime-fallback/error-classifier.ts +++ b/src/hooks/runtime-fallback/error-classifier.ts @@ -126,6 +126,8 @@ export function classifyErrorType(error: unknown): string | undefined { errorName?.includes("insufficientquota") || errorName?.includes("billingerror") || /quota.?exceeded/i.test(message) || + /exceeded.*quota/i.test(message) || + /usage\s*quota/i.test(message) || /subscription.*quota/i.test(message) || /insufficient.?(?:quota|balance|funds?)/i.test(message) || /billing.?(?:hard.?)?limit/i.test(message) || diff --git a/src/hooks/runtime-fallback/quota-error-classifier.regression.test.ts b/src/hooks/runtime-fallback/quota-error-classifier.regression.test.ts index 737db208c..5878e8f2a 100644 --- a/src/hooks/runtime-fallback/quota-error-classifier.regression.test.ts +++ b/src/hooks/runtime-fallback/quota-error-classifier.regression.test.ts @@ -57,7 +57,7 @@ describe("runtime-fallback quota error regressions", () => { expect(retryable).toBe(true) }) - test("classifies Volcano Engine 'exceeded the usage quota' as retryable", () => { + test("classifies Volcano Engine 'exceeded the usage quota' as quota_exceeded and retryable", () => { //#given const error = { name: "SessionRetry", @@ -65,9 +65,11 @@ describe("runtime-fallback quota error regressions", () => { } //#when + const errorType = classifyErrorType(error) const retryable = isRetryableError(error, [429, 500, 502, 503, 504]) //#then + expect(errorType).toBe("quota_exceeded") // Volcano Engine quota errors trigger fallback to the next model expect(retryable).toBe(true) })