fix: preserve streaming compaction auth errors

(cherry picked from commit 6fe25c6a08e169a15fca057a56e1ce36f46bc641)
This commit is contained in:
usr-bin-roygbiv
2026-07-26 21:37:38 +00:00
committed by can1357
parent 2fe31c61b6
commit 4c2b40f8b3
2 changed files with 35 additions and 2 deletions
@@ -21,6 +21,7 @@ import {
parseAzureDeploymentNameMap,
resolveOpenAIRequestSetup,
} from "@oh-my-pi/pi-ai/providers/openai-shared";
import { captureOpenAIHttpError } from "@oh-my-pi/pi-ai/utils/openai-http";
import {
CODEX_BASE_URL,
getCodexAccountId,
@@ -334,18 +335,19 @@ async function attemptCompactionV2Streaming(
});
if (!response.ok) {
const errorText = await response.text().catch(() => "");
const cause = await captureOpenAIHttpError(response);
logger.warn("V2 remote compaction failed", {
endpoint,
status: response.status,
statusText: response.statusText,
errorText,
errorText: cause.captured.bodyText ?? "",
});
throw new ProviderHttpError(
`V2 remote compaction failed (${response.status} ${response.statusText})`,
response.status,
{
headers: response.headers,
cause,
},
);
}
@@ -20,6 +20,7 @@ import {
trimRemoteCompactionInputToContextWindow,
} from "@oh-my-pi/pi-agent-core/compaction/openai";
import * as ai from "@oh-my-pi/pi-ai";
import * as AIError from "@oh-my-pi/pi-ai/error";
import { getOpenAICodexTransportDetails } from "@oh-my-pi/pi-ai/providers/openai-codex-responses";
import type {
AssistantMessage,
@@ -733,6 +734,36 @@ describe("requestCompactionV2Streaming", () => {
expect(attempts).toBe(2);
});
test("preserves auth_unavailable from V2 HTTP failures", async () => {
const model = makeOpenAiModel({
remoteCompaction: {
enabled: true,
v2StreamingEnabled: true,
v2Endpoint: "https://compact.example/v1/responses",
},
});
const request = buildCompactionV2Request(
model,
[{ type: "message", role: "user", content: [{ type: "input_text", text: "real user" }] }],
"instructions",
);
const fetchMock = vi.fn(async () =>
Response.json(
{ error: { type: "auth_unavailable", message: "no auth available for codex" } },
{ status: 503, statusText: "Service Unavailable" },
),
);
const error = await requestCompactionV2Streaming(model, "test-key", request, undefined, {
fetch: fetchMock,
retryWait: async () => {},
}).catch(cause => cause);
expect(fetchMock).toHaveBeenCalled();
expect(error).toBeInstanceOf(AIError.ProviderHttpError);
expect(AIError.is(AIError.classify(error), AIError.Flag.AuthFailed)).toBe(true);
});
});
describe("Responses Lite remote compaction", () => {