fix: preserve native compaction failures

(cherry picked from commit d13e9f30a06cad347226d2fa377cab8c086debc3)
This commit is contained in:
usr-bin-roygbiv
2026-07-30 01:42:53 +02:00
committed by can1357
parent 7fff8869a0
commit 9dd8d3c6ce
2 changed files with 34 additions and 1 deletions
@@ -2542,7 +2542,7 @@ export class SessionMaintenance {
candidate.api,
);
if (AIError.is(id, AIError.Flag.AuthFailed)) {
lastError = this.#buildCompactionAuthError();
if (!nativeCompactionFailure) lastError = this.#buildCompactionAuthError();
break;
}
if (AIError.is(id, AIError.Flag.Timeout)) {
@@ -190,6 +190,39 @@ describe("issue #986 compaction auth fallback", () => {
]);
});
it("preserves a native transport failure when a later same-provider candidate fails authentication", async () => {
const { apiKeySpy, crossProviderModel, currentModel, sameProviderModel, triggerAutoCompaction } =
await createAutoNativeFallbackSession();
apiKeySpy.mockImplementation(async model =>
model.provider === crossProviderModel.provider ? undefined : "test-key",
);
const attemptedModels: string[] = [];
let errorMessage: string | undefined;
session.subscribe(event => {
if (event.type === "auto_compaction_end") errorMessage = event.errorMessage;
});
vi.spyOn(compactionModule, "compact").mockImplementation(async (_preparation, model) => {
attemptedModels.push(`${model.provider}/${model.id}`);
if (model.provider === currentModel.provider && model.id === currentModel.id) {
throw new compactionModule.NativeCompactionError(new Error("native compaction transport failed"));
}
if (model.provider === sameProviderModel.provider && model.id === sameProviderModel.id) {
throw new compactionModule.NativeCompactionError(
Object.assign(new Error("native compaction authentication failed"), { status: 401 }),
);
}
throw new Error(`Unexpected compaction model ${model.provider}/${model.id}`);
});
await triggerAutoCompaction();
expect(attemptedModels).toEqual([
`${currentModel.provider}/${currentModel.id}`,
`${sameProviderModel.provider}/${sameProviderModel.id}`,
]);
expect(errorMessage).toContain("native compaction transport failed");
});
it("skips unauthenticated cross-provider candidates before enforcing the native boundary", async () => {
const { apiKeySpy, crossProviderModel, currentModel, sameProviderModel, triggerAutoCompaction } =
await createAutoNativeFallbackSession();