fix(recovery): restore compaction pipeline sufficient check and conservative charsPerToken
Fixes critical v2.10.0 compaction regression where truncation ALWAYS returned early without checking if it was sufficient, causing PHASE 3 (Summarize) to be skipped. This led to "history disappears" symptom where all context was lost after compaction. Changes: - Restored aggressiveResult.sufficient check before early return in executor - Only return from Truncate phase if truncation successfully reduced tokens below limit - Otherwise fall through to Summarize phase when truncation is insufficient - Restored conservative charsPerToken=4 (was changed to 2, too aggressive) - Added 2 regression tests: * Test 1: Verify Summarize is called when truncation is insufficient * Test 2: Verify Summarize is skipped when truncation is sufficient Regression details: - v2.10.0 changed charsPerToken from 4 to 2, making truncation too aggressive - Early return removed sufficient check, skipping fallback to Summarize - Users reported complete loss of conversation history after compaction 🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
@@ -401,21 +401,31 @@ export async function executeCompact(
|
||||
|
||||
log("[auto-compact] aggressive truncation completed", aggressiveResult);
|
||||
|
||||
clearSessionState(autoCompactState, sessionID);
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
await (client as Client).session.prompt_async({
|
||||
path: { sessionID },
|
||||
body: { parts: [{ type: "text", text: "Continue" }] },
|
||||
query: { directory },
|
||||
});
|
||||
} catch {}
|
||||
}, 500);
|
||||
return;
|
||||
// Only return early if truncation was sufficient to get under token limit
|
||||
// Otherwise fall through to PHASE 3 (Summarize)
|
||||
if (aggressiveResult.sufficient) {
|
||||
clearSessionState(autoCompactState, sessionID);
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
await (client as Client).session.prompt_async({
|
||||
path: { sessionID },
|
||||
body: { parts: [{ type: "text", text: "Continue" }] },
|
||||
query: { directory },
|
||||
});
|
||||
} catch {}
|
||||
}, 500);
|
||||
return;
|
||||
}
|
||||
// Truncation was insufficient - fall through to Summarize
|
||||
log("[auto-compact] truncation insufficient, falling through to summarize", {
|
||||
sessionID,
|
||||
truncatedCount: aggressiveResult.truncatedCount,
|
||||
sufficient: aggressiveResult.sufficient,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// PHASE 3: Summarize - fallback when no tool outputs to truncate
|
||||
// PHASE 3: Summarize - fallback when truncation insufficient or no tool outputs
|
||||
const retryState = getOrCreateRetryState(autoCompactState, sessionID);
|
||||
|
||||
if (errorData?.errorType?.includes("non-empty content")) {
|
||||
|
||||
Reference in New Issue
Block a user