fix(core): recover v2 context overflow (#31005)
This commit is contained in:
parent
c814f84c87
commit
820c984d47
18 changed files with 473 additions and 88 deletions
|
|
@ -73,6 +73,46 @@ const expectLLMError = (error: unknown) => {
|
|||
const errorHttp = (error: LLMError) => ("http" in error.reason ? error.reason.http : undefined)
|
||||
|
||||
describe("RequestExecutor", () => {
|
||||
it.effect("classifies context overflow responses", () =>
|
||||
Effect.gen(function* () {
|
||||
const executor = yield* RequestExecutor.Service
|
||||
const error = yield* executor.execute(request).pipe(Effect.flip)
|
||||
|
||||
expectLLMError(error)
|
||||
expect(error.reason).toMatchObject({ _tag: "InvalidRequest", classification: "context-overflow" })
|
||||
}).pipe(
|
||||
Effect.provide(
|
||||
responsesLayer([
|
||||
new Response('{"error":{"code":"context_length_exceeded","message":"prompt too long"}}', {
|
||||
status: 400,
|
||||
}),
|
||||
]),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
it.effect("does not classify generic HTTP 413 payload errors as context overflow", () =>
|
||||
Effect.gen(function* () {
|
||||
const executor = yield* RequestExecutor.Service
|
||||
const error = yield* executor.execute(request).pipe(Effect.flip)
|
||||
|
||||
expectLLMError(error)
|
||||
expect(error.reason).toMatchObject({ _tag: "InvalidRequest" })
|
||||
expect("classification" in error.reason ? error.reason.classification : undefined).toBeUndefined()
|
||||
}).pipe(Effect.provide(responsesLayer([new Response("request too large", { status: 413 })]))),
|
||||
)
|
||||
|
||||
it.effect("does not classify ordinary invalid requests as context overflow", () =>
|
||||
Effect.gen(function* () {
|
||||
const executor = yield* RequestExecutor.Service
|
||||
const error = yield* executor.execute(request).pipe(Effect.flip)
|
||||
|
||||
expectLLMError(error)
|
||||
expect(error.reason).toMatchObject({ _tag: "InvalidRequest" })
|
||||
expect("classification" in error.reason ? error.reason.classification : undefined).toBeUndefined()
|
||||
}).pipe(Effect.provide(responsesLayer([new Response("invalid parameter", { status: 400 })]))),
|
||||
)
|
||||
|
||||
it.effect("returns redacted diagnostics for retryable rate limits", () =>
|
||||
Effect.gen(function* () {
|
||||
const executor = yield* RequestExecutor.Service
|
||||
|
|
|
|||
|
|
@ -477,6 +477,29 @@ describe("Anthropic Messages route", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("classifies prompt-too-long provider errors", () =>
|
||||
Effect.gen(function* () {
|
||||
const response = yield* LLMClient.generate(request).pipe(
|
||||
Effect.provide(
|
||||
fixedResponse(
|
||||
sseEvents({
|
||||
type: "error",
|
||||
error: { type: "invalid_request_error", message: "prompt is too long: 210000 tokens" },
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
expect(response.events).toEqual([
|
||||
{
|
||||
type: "provider-error",
|
||||
message: "invalid_request_error: prompt is too long: 210000 tokens",
|
||||
classification: "context-overflow",
|
||||
},
|
||||
])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("falls back to error type when no message is present", () =>
|
||||
Effect.gen(function* () {
|
||||
const response = yield* LLMClient.generate(request).pipe(
|
||||
|
|
|
|||
|
|
@ -351,6 +351,23 @@ describe("Bedrock Converse route", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("classifies input-too-long validation exceptions", () =>
|
||||
Effect.gen(function* () {
|
||||
const response = yield* LLMClient.generate(baseRequest).pipe(
|
||||
Effect.provide(
|
||||
fixedBytes(eventStreamBody(["validationException", { message: "Input is too long for requested model" }])),
|
||||
),
|
||||
)
|
||||
|
||||
expect(response.events.find((event) => event.type === "provider-error")).toEqual({
|
||||
type: "provider-error",
|
||||
message: "Input is too long for requested model",
|
||||
classification: "context-overflow",
|
||||
retryable: false,
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("rejects requests with no auth path", () =>
|
||||
Effect.gen(function* () {
|
||||
const unsignedModel = AmazonBedrock.configure({
|
||||
|
|
|
|||
|
|
@ -1351,7 +1351,13 @@ describe("OpenAI Responses route", () => {
|
|||
),
|
||||
)
|
||||
|
||||
expect(response.events).toEqual([{ type: "provider-error", message: "context_length_exceeded: prompt too long" }])
|
||||
expect(response.events).toEqual([
|
||||
{
|
||||
type: "provider-error",
|
||||
message: "context_length_exceeded: prompt too long",
|
||||
classification: "context-overflow",
|
||||
},
|
||||
])
|
||||
}),
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue