fix(memoryFlush): guard transcript-size forced flush against repeated runs#32358
Conversation
… runs The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]>
|
@steipete — The |
Greptile SummaryThis PR fixes a regression (introduced in Changes:
The fix is minimal, focused, and correctly mirrors the existing compaction-guard semantics. The Confidence Score: 5/5
Last reviewed commit: 9690ed1 |
… runs (openclaw#32358) The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]> (cherry picked from commit 503d395)
… runs (openclaw#32358) The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]>
… runs (openclaw#32358) The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]>
… runs (openclaw#32358) The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]>
… runs (openclaw#32358) The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]>
… runs (openclaw#32358) The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]>
… runs (openclaw#32358) The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]>
… runs (openclaw#32358) The `forceFlushTranscriptBytes` path (introduced in d729ab2) bypasses the `memoryFlushCompactionCount` guard that prevents repeated flushes within the same compaction cycle. Once the session transcript exceeds 2 MB, memory flush fires on every single message — even when token count is well under the compaction threshold. Extract `hasAlreadyFlushedForCurrentCompaction()` from the inline guard in `shouldRunMemoryFlush` and apply it to both the token-based and the transcript-size trigger paths. Fixes openclaw#32317 Signed-off-by: HCL <[email protected]>
Summary
Fixes #32317 — Pre-compaction memory flush fires on every message after v2026.3.1 upgrade.
Root cause:
agent-runner-memory.ts:440— theshouldForceFlushByTranscriptSizepath (introduced ind729ab21) is OR'd into the flush decision without thememoryFlushCompactionCountguard. The token-based path inshouldRunMemoryFlush()correctly checksmemoryFlushCompactionCount === compactionCountto prevent repeated flushes within the same compaction cycle, but the transcript-size path bypasses this check.With tool calls and heartbeats, transcript file size grows fast in bytes even at low token counts (reporter shows 49k/200k tokens). Once the 2 MB
forceFlushTranscriptBytesdefault is crossed, forced flush fires on every single message.Fix: Extract
hasAlreadyFlushedForCurrentCompaction()from the inline guard and apply it to both trigger paths.Changes
src/auto-reply/reply/memory-flush.tshasAlreadyFlushedForCurrentCompaction()helper (+14/-3)src/auto-reply/reply/agent-runner-memory.tssrc/auto-reply/reply/reply-state.test.tshasAlreadyFlushedForCurrentCompaction()(+37)Test plan
vitest run src/auto-reply/reply/reply-state.test.ts: 27/27 passlobster-biscuit