diff --git a/extensions/qa-lab/src/scenario-catalog-compaction.test.ts b/extensions/qa-lab/src/scenario-catalog-compaction.test.ts index 3d7a32d17da0..1efb40af925a 100644 --- a/extensions/qa-lab/src/scenario-catalog-compaction.test.ts +++ b/extensions/qa-lab/src/scenario-catalog-compaction.test.ts @@ -72,6 +72,7 @@ describe("qa compaction scenario catalog", () => { const writeTranscriptToolCallIdExpr = readSetExpression("writeTranscriptToolCallId"); const continuationChainExpr = readSetExpression("continuationChain"); const compactionSummaryRequestsExpr = readSetExpression("compactionSummaryRequests"); + const overflowCheckpointsExpr = readSetExpression("overflowCheckpoints"); const continuationAssertIndex = actionIndex((action) => readFlowAssertExpression(action).includes("continuationChain.valid === true"), ); @@ -100,6 +101,10 @@ describe("qa compaction scenario catalog", () => { ); const compactionSummaryAssertExpr = readAssertExpression("compactionSummaryRequests.some"); const noQualityRetryAssertExpr = readAssertExpression("Previous summary failed quality checks"); + const compactionSnapshotAssertExpr = readAssertExpression( + "Number.isInteger(sessionEntry?.compactionCount)", + ); + const overflowCheckpointAssertExpr = readAssertExpression("overflowCheckpoints.length === 1"); const knownGap = "known-harness-gap compaction-retry-mutating-tool: provider-error recovery does not invoke Codex native compaction; native token-threshold compaction needs a separate scenario."; @@ -288,6 +293,16 @@ describe("qa compaction scenario catalog", () => { expect(noQualityRetryAssertExpr).toContain( "!String(request.allInputText ?? '').includes('Previous summary failed quality checks')", ); + expect(compactionSnapshotAssertExpr).toContain( + "Number.isInteger(sessionEntry?.compactionCount) && sessionEntry.compactionCount >= 1", + ); + expect(compactionSnapshotAssertExpr).toContain( + "Number.isFinite(sessionEntry?.totalTokens) && sessionEntry?.totalTokensFresh === true", + ); + expect(compactionSnapshotAssertExpr).not.toContain("compactionCount === 1"); + expect(flow).not.toContain("sessionEntry?.compactionCount === 1"); + expect(overflowCheckpointsExpr).toContain("checkpoint.reason === 'overflow-retry'"); + expect(overflowCheckpointAssertExpr).toContain("overflowCheckpoints.length === 1"); expect(flow).not.toContain("compactionSummaryRequests.length === 1"); expect(flow).toContain( "writeRequest.rawByteLength < config.overflowThresholdBytes && writeRequest.rawByteLength < overflowRequest.rawByteLength", diff --git a/qa/scenarios/runtime/compaction-retry-mutating-tool.yaml b/qa/scenarios/runtime/compaction-retry-mutating-tool.yaml index 64687d7b7d90..4f50d088cd06 100644 --- a/qa/scenarios/runtime/compaction-retry-mutating-tool.yaml +++ b/qa/scenarios/runtime/compaction-retry-mutating-tool.yaml @@ -244,9 +244,9 @@ flow: value: expr: "store[sessionKey]" - assert: - expr: "sessionEntry?.compactionCount === 1 && Number.isFinite(sessionEntry?.totalTokens) && sessionEntry?.totalTokensFresh === true" + expr: "Number.isInteger(sessionEntry?.compactionCount) && sessionEntry.compactionCount >= 1 && Number.isFinite(sessionEntry?.totalTokens) && sessionEntry?.totalTokensFresh === true" message: - expr: "`OpenClaw token snapshot was not fresh after one compaction: ${JSON.stringify({ compactionCount: sessionEntry?.compactionCount, totalTokens: sessionEntry?.totalTokens, totalTokensFresh: sessionEntry?.totalTokensFresh })}`" + expr: "`OpenClaw token snapshot did not retain a positive compaction count with fresh token data: ${JSON.stringify({ compactionCount: sessionEntry?.compactionCount, totalTokens: sessionEntry?.totalTokens, totalTokensFresh: sessionEntry?.totalTokensFresh })}`" - set: checkpointPage value: expr: "await env.gateway.call('sessions.compaction.list', { key: sessionKey }, { timeoutMs: 15000 })"