mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-20 00:02:54 +00:00
test(server): retain compacted rewind diagnostic
Reproduces stale compaction references through the current transcript-store path. Native resume of the synthetic source, fork, and repaired control succeeds, so this is not evidence of the reported context overflow. Co-authored-by: kesiyuan <kesiyuan@bytedance.com>
This commit is contained in:
co-authored by
kesiyuan
parent
f22775a8e1
commit
dbfb0c71ef
@@ -0,0 +1,86 @@
|
||||
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { expect, test } from "vitest";
|
||||
import { realClaudeRewindSdk, revertClaudeConversation } from "./rewind.js";
|
||||
|
||||
interface TranscriptEntry {
|
||||
uuid: string;
|
||||
sessionId: string;
|
||||
subtype?: string;
|
||||
forkedFrom?: { messageUuid: string };
|
||||
compactMetadata?: {
|
||||
preservedSegment: {
|
||||
headUuid: string;
|
||||
anchorUuid: string;
|
||||
tailUuid: string;
|
||||
};
|
||||
preservedMessages: {
|
||||
anchorUuid: string;
|
||||
uuids: string[];
|
||||
allUuids: string[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function parseEntries(text: string): TranscriptEntry[] {
|
||||
return text
|
||||
.trim()
|
||||
.split("\n")
|
||||
.map((line) => JSON.parse(line) as TranscriptEntry);
|
||||
}
|
||||
|
||||
// Fixture from PR #3938, commit 374b08f9d56d9dabc62f8e4e01acc73d1c619548.
|
||||
// This proves stale metadata, not the reported model context overflow.
|
||||
test("keeps compaction references attached to forked messages", async () => {
|
||||
const root = await mkdtemp(path.join(process.cwd(), ".compacted-rewind-"));
|
||||
try {
|
||||
const fixture = await readFile(
|
||||
new URL(
|
||||
"./test-fixtures/issue-3837-compacted-session.jsonl",
|
||||
import.meta.url
|
||||
),
|
||||
"utf8"
|
||||
);
|
||||
const entries = parseEntries(fixture);
|
||||
const sourceSessionId = entries[0]!.sessionId;
|
||||
const transcriptPath = path.join(root, `${sourceSessionId}.jsonl`);
|
||||
await writeFile(transcriptPath, fixture);
|
||||
let forkId = sourceSessionId;
|
||||
await revertClaudeConversation({
|
||||
sdk: realClaudeRewindSdk,
|
||||
sessionId: sourceSessionId,
|
||||
transcriptPath,
|
||||
messageId: entries.at(-1)!.uuid,
|
||||
setSessionId: (id) => {
|
||||
forkId = id;
|
||||
},
|
||||
});
|
||||
const fork = parseEntries(
|
||||
await readFile(path.join(root, `${forkId}.jsonl`), "utf8")
|
||||
);
|
||||
const ids = new Map(
|
||||
fork.map((entry) => [entry.forkedFrom?.messageUuid, entry.uuid])
|
||||
);
|
||||
const remap = (id: string) => ids.get(id) ?? id;
|
||||
const source = entries.find(
|
||||
(entry) => entry.subtype === "compact_boundary"
|
||||
)!.compactMetadata!;
|
||||
const actual = fork.find((entry) => entry.subtype === "compact_boundary")!
|
||||
.compactMetadata!;
|
||||
expect(actual).toEqual({
|
||||
...source,
|
||||
preservedSegment: {
|
||||
headUuid: remap(source.preservedSegment.headUuid),
|
||||
anchorUuid: remap(source.preservedSegment.anchorUuid),
|
||||
tailUuid: remap(source.preservedSegment.tailUuid),
|
||||
},
|
||||
preservedMessages: {
|
||||
anchorUuid: remap(source.preservedMessages.anchorUuid),
|
||||
uuids: source.preservedMessages.uuids.map(remap),
|
||||
allUuids: source.preservedMessages.allUuids.map(remap),
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{"type":"user","uuid":"10000000-0000-4000-8000-000000000002","parentUuid":null,"isSidechain":false,"sessionId":"10000000-0000-4000-8000-000000000001","timestamp":"2026-08-27T08:00:00.000Z","message":{"role":"user","content":"Before compaction"}}
|
||||
{"type":"assistant","uuid":"10000000-0000-4000-8000-000000000003","parentUuid":"10000000-0000-4000-8000-000000000002","isSidechain":false,"sessionId":"10000000-0000-4000-8000-000000000001","timestamp":"2026-08-27T08:00:00.000Z","message":{"role":"assistant","content":[{"type":"text","text":"Done"}]}}
|
||||
{"type":"system","subtype":"stop_hook_summary","uuid":"10000000-0000-4000-8000-000000000004","parentUuid":"10000000-0000-4000-8000-000000000003","isSidechain":false,"sessionId":"10000000-0000-4000-8000-000000000001","timestamp":"2026-08-27T08:00:00.000Z"}
|
||||
{"type":"system","subtype":"compact_boundary","uuid":"10000000-0000-4000-8000-000000000005","parentUuid":null,"logicalParentUuid":"10000000-0000-4000-8000-000000000004","isSidechain":false,"sessionId":"10000000-0000-4000-8000-000000000001","timestamp":"2026-08-27T08:00:00.000Z","compactMetadata":{"trigger":"auto","preTokens":900000,"preservedSegment":{"headUuid":"10000000-0000-4000-8000-000000000003","anchorUuid":"10000000-0000-4000-8000-000000000006","tailUuid":"10000000-0000-4000-8000-000000000004"},"preservedMessages":{"anchorUuid":"10000000-0000-4000-8000-000000000006","uuids":["10000000-0000-4000-8000-000000000003","10000000-0000-4000-8000-000000000004"],"allUuids":["10000000-0000-4000-8000-000000000003","10000000-0000-4000-8000-000000000008","10000000-0000-4000-8000-000000000004"]},"postTokens":10000}}
|
||||
{"type":"user","uuid":"10000000-0000-4000-8000-000000000006","parentUuid":"10000000-0000-4000-8000-000000000005","isSidechain":false,"isCompactSummary":true,"sessionId":"10000000-0000-4000-8000-000000000001","timestamp":"2026-08-27T08:00:00.000Z","message":{"role":"user","content":"Compacted summary"}}
|
||||
{"type":"user","uuid":"10000000-0000-4000-8000-000000000007","parentUuid":"10000000-0000-4000-8000-000000000006","isSidechain":false,"sessionId":"10000000-0000-4000-8000-000000000001","timestamp":"2026-08-27T08:00:00.000Z","message":{"role":"user","content":"Continue after compaction"}}
|
||||
Reference in New Issue
Block a user