fix: cancel compaction instead of truncating history when summarization fails#10711
Conversation
Additional Comments (2)
const newContentRatio = (newContentTokens / contextWindowTokens) * 100;
const newContentRatio = (newContentTokens / contextWindowTokens) * 100;Remove one of these declarations. Prompt To Fix With AIThis is a comment left during a code review.
Path: src/agents/pi-extensions/compaction-safeguard.ts
Line: 213:217
Comment:
**Duplicate variable redeclared**
`newContentRatio` is declared twice in the same block, which will cause a TS/JS syntax error and fail the build:
```ts
const newContentRatio = (newContentTokens / contextWindowTokens) * 100;
const newContentRatio = (newContentTokens / contextWindowTokens) * 100;
```
Remove one of these declarations.
```suggestion
const newContentRatio = (newContentTokens / contextWindowTokens) * 100;
```
How can I resolve this? If you propose a fix, please make it concise.
This test constructs an Prompt To Fix With AIThis is a comment left during a code review.
Path: src/agents/pi-extensions/compaction-safeguard.test.ts
Line: 102:105
Comment:
**Flaky `Date.now()` in test**
This test constructs an `AgentMessage` with `timestamp: Date.now()`. If other tests/assertions depend on stable timestamps (or snapshots), this can introduce nondeterminism. Prefer a fixed timestamp (e.g. `0` or a constant) for test data.
```suggestion
messagesToSummarize: [{ role: "user", content: "hello", timestamp: 0 }],
```
How can I resolve this? If you propose a fix, please make it concise. |
|
Thanks for the review! Addressing both points:
|
|
Clean fix. All three failure paths now return One thing that could strengthen it: a live integration test verifying that summarization works when model and key are available. The failure paths are covered by unit tests, but for an LLM integration, a test hitting a real API (skipped in CI, opt-in via env var) would help catch regressions mocks can miss. Also filed #10099 independently with the same bug report, linking for reference. |
|
@Drickon Thanks for the review and the kind words! Really appreciate you taking the time. You're right — just pushed a fix for the leftover Re: live integration test — great suggestion. I'll look into adding an opt-in test gated behind an env var (e.g. Also noted the link to #10099 — thanks for the independent confirmation of the issue. |
bfc1ccb to
f92900f
Compare
|
This pull request has been automatically marked as stale due to inactivity. |
0166847 to
521498c
Compare
|
Rebased onto current main — merge conflicts resolved. All changes intact: three failure paths return The conflict was in @Drickon Re: integration test for the success path — still on my list, will follow up in a separate PR to keep this one focused on the cancel-on-failure fix. |
…on fails
When the compaction safeguard cannot generate a summary (no model, no API
key, or LLM error), it previously returned a "Summary unavailable" fallback
string and still truncated history. This caused irreversible data loss -
older messages were discarded even though no meaningful summary was produced.
Now returns `{ cancel: true }` in all three failure paths so the framework
aborts compaction entirely and preserves the full conversation history.
Fixes openclaw#10332
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com>
521498c to
eb9e4a5
Compare
|
Rebased this branch onto current What I updated:
Validation run after rebase:
This should now be merge-ready from a conflicts/tests/changelog standpoint. |
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
|
Makes sense keeping it focused. Look forward to the follow-up PR. |
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org> (cherry picked from commit ea47ab2) # Conflicts: # src/agents/pi-extensions/compaction-safeguard.test.ts # src/agents/pi-extensions/compaction-safeguard.ts
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org> (cherry picked from commit ea47ab2) # Conflicts: # src/agents/pi-extensions/compaction-safeguard.test.ts # src/agents/pi-extensions/compaction-safeguard.ts
…on fails (openclaw#10711) * fix: cancel compaction instead of truncating history when summarization fails When the compaction safeguard cannot generate a summary (no model, no API key, or LLM error), it previously returned a "Summary unavailable" fallback string and still truncated history. This caused irreversible data loss - older messages were discarded even though no meaningful summary was produced. Now returns `{ cancel: true }` in all three failure paths so the framework aborts compaction entirely and preserves the full conversation history. Fixes openclaw#10332 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: use deterministic timestamps in compaction safeguard tests Replace Date.now() with fixed timestamp (0) in test data to prevent nondeterministic behavior in snapshot-based or order-dependent tests. Co-authored-by: Cursor <cursoragent@cursor.com> * Changelog: note compaction cancellation safeguard fix --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Human View
Summary
Fixes #10332
When the compaction safeguard cannot produce a real summary (no model configured, no API key available, or the LLM call fails), it currently returns a
"Summary unavailable"fallback and still truncates history viafirstKeptEntryId. This causes irreversible data loss — users lose older conversation context with no way to recover it.Changes
compaction-safeguard.tsnow return{ cancel: true }instead of{ compaction: { summary: fallbackSummary, ... } }!model→ cancel!apiKey→ cancelcatch (error)→ cancelconsole.warn()on each path for observabilityWhy
cancelworksThe
pi-coding-agentframework explicitly supportsSessionBeforeCompactResult.cancel— when the extension returns{ cancel: true }, the framework throws"Compaction cancelled"and preserves the full message history. The session will retry compaction on the next turn when conditions (model/key/API) may have recovered.Test plan
summarizeInStagesthrows (mocked)npx vitest run src/agents/pi-extensions/compaction-safeguard.test.ts)AI View (DCCE Protocol v1.0)
Metadata
AI Contribution Summary
Verification Steps Performed
Human Review Guidance
compaction-safeguard.ts,SessionBeforeCompactResult.cancel,console.warnMade with M7 Cursor
Greptile Overview
Greptile Summary
compaction-safeguardto return{ cancel: true }(withconsole.warn) when no model, no API key, or summarization throws, so history is preserved instead of truncated with a fallback summary.session_before_compacthandler and mockingsummarizeInStages.compactionpayload when summarization succeeds.Confidence Score: 3/5
compaction-safeguard.tsincludes a duplicatedconstdeclaration that will fail TypeScript/JS parsing and block builds.