From 243db8d0f536beee1c2fedced86beed138872046 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 3 Apr 2026 18:07:47 +0900 Subject: [PATCH] fix: clear failed empty-content recovery state --- .../summarize-retry-strategy.test.ts | 49 +++++++++++++++++++ .../summarize-retry-strategy.ts | 1 + 2 files changed, 50 insertions(+) diff --git a/src/hooks/anthropic-context-window-limit-recovery/summarize-retry-strategy.test.ts b/src/hooks/anthropic-context-window-limit-recovery/summarize-retry-strategy.test.ts index 7c2e25b69..2c0137c8b 100644 --- a/src/hooks/anthropic-context-window-limit-recovery/summarize-retry-strategy.test.ts +++ b/src/hooks/anthropic-context-window-limit-recovery/summarize-retry-strategy.test.ts @@ -151,4 +151,53 @@ describe("runSummarizeRetryStrategy", () => { //#then expect(autoCompactState.retryStateBySession.has(sessionID)).toBe(false) }) + + test("#given max empty-content recovery attempts reached #when summarize retry exits early #then it clears full recovery state", async () => { + //#given + autoCompactState.pendingCompact.add(sessionID) + autoCompactState.errorDataBySession.set(sessionID, { + currentTokens: 250000, + maxTokens: 200000, + errorType: "non-empty content", + }) + autoCompactState.retryStateBySession.set(sessionID, { + attempt: 1, + lastAttemptTime: Date.now(), + firstAttemptTime: Date.now(), + }) + autoCompactState.truncateStateBySession.set(sessionID, { + truncateAttempt: 2, + }) + autoCompactState.emptyContentAttemptBySession.set(sessionID, 3) + autoCompactState.retryTimerBySession.set( + sessionID, + 1 as unknown as ReturnType, + ) + + //#when + await runSummarizeRetryStrategy({ + sessionID, + msg: { providerID: "anthropic", modelID: "claude-sonnet-4-6" }, + autoCompactState, + client: client as never, + directory, + pluginConfig: {} as OhMyOpenCodeConfig, + errorType: "non-empty content", + }) + + //#then + expect(autoCompactState.pendingCompact.has(sessionID)).toBe(false) + expect(autoCompactState.errorDataBySession.has(sessionID)).toBe(false) + expect(autoCompactState.retryStateBySession.has(sessionID)).toBe(false) + expect(autoCompactState.retryTimerBySession.has(sessionID)).toBe(false) + expect(autoCompactState.truncateStateBySession.has(sessionID)).toBe(false) + expect(autoCompactState.emptyContentAttemptBySession.has(sessionID)).toBe(false) + expect(showToastMock).toHaveBeenCalledWith( + expect.objectContaining({ + body: expect.objectContaining({ + title: "Recovery Failed", + }), + }), + ) + }) }) diff --git a/src/hooks/anthropic-context-window-limit-recovery/summarize-retry-strategy.ts b/src/hooks/anthropic-context-window-limit-recovery/summarize-retry-strategy.ts index 2440f699d..f7d527d3c 100644 --- a/src/hooks/anthropic-context-window-limit-recovery/summarize-retry-strategy.ts +++ b/src/hooks/anthropic-context-window-limit-recovery/summarize-retry-strategy.ts @@ -73,6 +73,7 @@ export async function runSummarizeRetryStrategy(params: { return } } else { + clearSessionState(params.autoCompactState, params.sessionID) await params.client.tui .showToast({ body: {