Skip to content

Commit fe44ece

Browse files
committed
fix: avoid reading body for Codex pool quota retry
1 parent cfe9bd0 commit fe44ece

2 files changed

Lines changed: 13 additions & 8 deletions

File tree

‎src/server/responses/core.ts‎

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ import type { WsData } from "../ws-bridge";
103103
import { registerTurn, trackStreamLifetime, unregisterTurn } from "../lifecycle";
104104
import { redactSecretString } from "../../lib/redact";
105105
import { readBoundedResponseBody } from "../../lib/bounded-body";
106-
import { classifyCodexPreStreamRejection } from "../../codex/quota-rejection";
107106
import type { AdmissionLease } from "../../lib/admission";
108107
import { supportedLadderFor } from "../effort-policy";
109108
import { isThreadSpawnRequest } from "../effort-policy";
@@ -247,12 +246,8 @@ async function shouldRetryCodexPoolAccountModel400(
247246
}
248247

249248
/** Pre-stream quota/billing rejections that warrant one alternate-account attempt (#584). */
250-
async function shouldRetryCodexPoolAccountQuota(
251-
response: Response,
252-
signal?: AbortSignal,
253-
): Promise<boolean> {
254-
const rejection = await classifyCodexPreStreamRejection(response, { signal });
255-
return rejection.alternateRetryEligible;
249+
export function shouldRetryCodexPoolAccountQuota(response: Response): boolean {
250+
return response.status === 402 || response.status === 429;
256251
}
257252

258253
interface CodexPoolAccountRetryArgs {
@@ -1630,7 +1625,7 @@ async function handleResponsesInner(
16301625
options.abortSignal,
16311626
)) {
16321627
poolRetryOutcome = 400;
1633-
} else if (await shouldRetryCodexPoolAccountQuota(upstreamResponse, options.abortSignal)) {
1628+
} else if (shouldRetryCodexPoolAccountQuota(upstreamResponse)) {
16341629
// Pre-stream only: once SSE has begun, mid-stream quota stays terminal.
16351630
poolRetryOutcome = upstreamResponse.status;
16361631
}

‎tests/codex-quota-rejection.test.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, expect, test } from "bun:test";
22
import { classifyCodexPreStreamRejection } from "../src/codex/quota-rejection";
3+
import { shouldRetryCodexPoolAccountQuota } from "../src/server/responses/core";
34

45
function jsonRejection(status: number, error: Record<string, unknown>): Response {
56
return Response.json({ error }, { status });
@@ -10,6 +11,15 @@ function jsonPayload(status: number, payload: Record<string, unknown>): Response
1011
}
1112

1213
describe("Codex pre-stream quota rejection classification", () => {
14+
test.each([
15+
[402, true],
16+
[429, true],
17+
[400, false],
18+
[503, false],
19+
])("selects pool-account retries synchronously for HTTP %i", (status, expected) => {
20+
expect(shouldRetryCodexPoolAccountQuota(new Response(null, { status }))).toBe(expected);
21+
});
22+
1323
test.each([
1424
[429, "nested code", { error: { code: "usage_limit_exceeded" } }, "usage_limit_exceeded"],
1525
[429, "nested type", { error: { type: "insufficient_quota" } }, "insufficient_quota"],

0 commit comments

Comments
 (0)