From 767f5a61485007a0b02a0663161d93b32b001b2f Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 25 May 2026 17:09:19 +0900 Subject: [PATCH] fix(model-core): retry OpenAI usage_limit_reached fallbacks Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- ...error-classifier-openai-usage-limit.test.ts | 18 ++++++++++++++++++ .../src/model-error-classifier.test.ts | 4 ++-- .../model-core/src/model-error-classifier.ts | 3 ++- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 packages/model-core/src/model-error-classifier-openai-usage-limit.test.ts diff --git a/packages/model-core/src/model-error-classifier-openai-usage-limit.test.ts b/packages/model-core/src/model-error-classifier-openai-usage-limit.test.ts new file mode 100644 index 000000000..0d6f2dc7b --- /dev/null +++ b/packages/model-core/src/model-error-classifier-openai-usage-limit.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, test } from "bun:test" +import { shouldRetryError } from "./model-error-classifier" + +describe("model-error-classifier OpenAI usage_limit_reached", () => { + test("treats OpenAI usage_limit_reached response bodies as retryable provider exhaustion", () => { + //#given + const error = { + name: "AI_APICallError", + message: '{"error":{"type":"usage_limit_reached","message":"The usage limit has been reached"}}', + } + + //#when + const result = shouldRetryError(error) + + //#then + expect(result).toBe(true) + }) +}) diff --git a/packages/model-core/src/model-error-classifier.test.ts b/packages/model-core/src/model-error-classifier.test.ts index 172899e64..43096fc5a 100644 --- a/packages/model-core/src/model-error-classifier.test.ts +++ b/packages/model-core/src/model-error-classifier.test.ts @@ -172,7 +172,7 @@ describe("model-error-classifier", () => { expect(result).toBe(false) }) - test("treats usage limit reached message as non-retryable STOP error (no error name)", () => { + test("treats provider usage limit reached message as retryable fallback signal", () => { //#given const error = { message: "usage limit has been reached for your account" } @@ -180,7 +180,7 @@ describe("model-error-classifier", () => { const result = shouldRetryError(error) //#then - expect(result).toBe(false) + expect(result).toBe(true) }) test("treats insufficient credits message as non-retryable STOP error (no error name)", () => { diff --git a/packages/model-core/src/model-error-classifier.ts b/packages/model-core/src/model-error-classifier.ts index 0786cd9fe..f9f5b3e5e 100644 --- a/packages/model-core/src/model-error-classifier.ts +++ b/packages/model-core/src/model-error-classifier.ts @@ -40,6 +40,8 @@ const NON_RETRYABLE_ERROR_NAMES = new Set([ const RETRYABLE_MESSAGE_PATTERNS = [ "rate_limit", "rate limit", + "usage_limit_reached", + "usage limit has been reached", "quota", "all credentials for model", "cooling down", @@ -92,7 +94,6 @@ const RETRYABLE_MESSAGE_PATTERNS = [ const STOP_MESSAGE_PATTERNS = [ "quota will reset after", "quota exceeded", - "usage limit has been reached", "free usage limit", "billing limit", "billing hard limit",