Auto-compact may run before session memory extraction finishes (race condition)
Description
The last few messages in a session can be lost during auto-compaction due to a race condition with session memory extraction.
Background
Session memory extraction runs asynchronously after each turn. Auto-compaction can trigger at the start of a new turn when token count exceeds the threshold.
The wait function (MC2/oj2) only waits while session memory is actively running - it checks a timestamp variable that's set when extraction starts and cleared when it finishes:
async function waitForSessionMemory() {
while (sessionMemoryStartedTimestamp) { // Only waits if currently running
if (Date.now() - sessionMemoryStartedTimestamp > 60000) return; // Stale
if (Date.now() - waitStart > 15000) return; // Timeout
await sleep(1000);
}
}
The Problem
If session memory extraction hasn't started yet when auto-compact triggers (due to debouncing or timing), the wait function returns immediately because the timestamp variable is undefined. Compaction then proceeds without the latest session memory.
Result: The last few messages/prompts may not be included in the session memory summary, effectively losing that context after compaction.
Timeline
- User sends message, turn completes
- Session memory extraction is queued (debounced)
- User sends another message
- Token threshold exceeded → auto-compact triggers
- Wait function called, but
sessionMemoryStartedTimestampis stillundefined - Wait returns immediately
- Compaction runs with stale session memory
- Session memory extraction finally runs (too late)
- Latest context is lost
Suggested Fix
Move the wait call earlier in the auto-compact flow, or ensure session memory extraction is triggered synchronously before checking whether to wait.
Thanks!