Skip to content

Commit 16cd50d

Browse files
authored
fix(ai): keep known throttles out of overflow matching (#58866)
1 parent d7e56bc commit 16cd50d

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

‎packages/ai/src/provider-error.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ export function classifyProviderFailure(input: ProviderFailure): AIError["reason
262262
(codes.includes("context_length_exceeded") ||
263263
codes.includes("model_context_window_exceeded") ||
264264
codes.includes("request_too_large") ||
265-
isContextOverflow(text))
265+
(!codes.includes("throttlingexception") && isContextOverflow(text)))
266266
)
267267
return new InvalidRequestError({ ...details, classification: "context-overflow" })
268268
if (input.status === 413 || isPayloadTooLarge(text))

‎packages/ai/test/provider-error.test.ts‎

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, expect, test } from "bun:test"
22
import { isContextOverflow, isContextOverflowFailure, isRetryable } from "../src/effect.js"
3-
import { AIError } from "../src/schema/index.js"
3+
import { AIError, HttpContext } from "../src/schema/index.js"
44
import { classifyProviderFailure, providerErrorMessage } from "../src/provider-error.js"
55

66
describe("provider error classification", () => {
@@ -449,6 +449,37 @@ describe("provider error classification", () => {
449449
expect(isContextOverflow("Too many tokens")).toBe(true)
450450
})
451451

452+
test("does not infer context overflow from known throttling exceptions", () => {
453+
const cases = [
454+
{ status: 429, data: { code: "ThrottlingException" } },
455+
{ status: 429, rawBody: '{"__type":"com.amazonaws.bedrock#ThrottlingException"}' },
456+
{ rawBody: '{"exception":{"type":"throttlingException"}}' },
457+
{
458+
status: 429,
459+
http: new HttpContext({
460+
url: "https://bedrock.test/model/example/converse-stream",
461+
status: 429,
462+
headers: { "x-amzn-errortype": "ThrottlingException:http://internal.amazon.com/coral/" },
463+
}),
464+
},
465+
]
466+
for (const input of cases) {
467+
for (const message of ["Token limit exceeded", "Too many tokens, please try again later"]) {
468+
const error = new AIError({ reason: classifyProviderFailure({ ...input, message }) })
469+
expect(error.reason._tag).toBe("RateLimit")
470+
expect(isContextOverflowFailure(error)).toBe(false)
471+
expect(isRetryable(error)).toBe(true)
472+
}
473+
}
474+
expect(
475+
classifyProviderFailure({
476+
message: "prompt is too long",
477+
status: 400,
478+
data: { code: "ValidationException" },
479+
}),
480+
).toMatchObject({ _tag: "InvalidRequest", classification: "context-overflow" })
481+
})
482+
452483
test("does not let substituted server codes make a 4xx retryable", () => {
453484
const openai = { error: { type: "server_error", message: "Upstream request failed: Model is unavailable." } }
454485
const anthropic = {

0 commit comments

Comments
 (0)