fix(replay): mark local compaction calls

This commit is contained in:
Tianyi Cui
2026-08-08 02:16:17 +08:00
parent d301dbdc7d
commit 8dcfe5c406
29 changed files with 147 additions and 50 deletions

View File

@@ -202,6 +202,7 @@ describe('deriveReplayScript', () => {
data: {
summary: rawOutput,
rawOutput,
llmStreamCall: true,
shadowedRange: { start: 1, end: 1 },
shadowedSeqs: [1],
shadowedTokenCount: 20,
@@ -238,6 +239,45 @@ describe('deriveReplayScript', () => {
expect(deriveReplayScript([event])).toEqual([])
})
it('does not infer a local LLM call from external compact output', () => {
const block = { type: 'text' as const, text: 'remote summary' }
const event: SessionEvent<'compact/summary'> = {
type: 'compact/summary',
seq: 1,
time: 0,
data: {
summary: [block],
rawOutput: [block],
shadowedRange: { start: 1, end: 1 },
shadowedSeqs: [1],
shadowedTokenCount: 20,
provider: 'remote',
model: 'remote',
},
}
expect(deriveReplayScript([event])).toEqual([])
})
it('rejects a marked compact LLM call without its complete output', () => {
const event: SessionEvent<'compact/summary'> = {
type: 'compact/summary',
seq: 1,
time: 0,
data: {
summary: [{ type: 'text', text: 'incomplete provenance' }],
llmStreamCall: true,
shadowedRange: { start: 1, end: 1 },
shadowedSeqs: [1],
shadowedTokenCount: 20,
provider: 'mock',
model: 'mock',
},
}
expect(() => deriveReplayScript([event])).toThrow(/LLM stream call without rawOutput/)
})
it('derives a compact/summary stream when usage is unavailable', () => {
const block = { type: 'text' as const, text: 'summary without usage' }
const event: SessionEvent<'compact/summary'> = {
@@ -247,6 +287,7 @@ describe('deriveReplayScript', () => {
data: {
summary: [block],
rawOutput: [block],
llmStreamCall: true,
shadowedRange: { start: 1, end: 1 },
shadowedSeqs: [1],
shadowedTokenCount: 20,
@@ -289,6 +330,27 @@ describe('deriveReplayScript', () => {
]
expect(() => deriveReplayScript(events)).toThrow(/model call 1\/1 ended without a finish chunk/)
})
it('rejects an unfinished call at a compact summary boundary', () => {
const events: SessionEvent[] = [
chunkEvent(1, 1, 1, { type: 'block-start', index: 0, blockType: 'text' }),
{
type: 'compact/summary',
seq: 2,
time: 0,
data: {
summary: [{ type: 'text', text: 'external checkpoint' }],
shadowedRange: { start: 1, end: 1 },
shadowedSeqs: [1],
shadowedTokenCount: 20,
provider: 'external',
model: 'external',
},
},
]
expect(() => deriveReplayScript(events)).toThrow(/model call 1\/1 ended without a finish chunk/)
})
})
describe('loadReplayScript', () => {