






















@@ -67,8 +67,15 @@ describe("runMemoryFlushIfNeeded", () => {
6767};
6868if (typeof params.newSessionId === "string" && params.newSessionId) {
6969nextEntry.sessionId = params.newSessionId;
70-const storePath = typeof params.storePath === "string" ? params.storePath : rootDir;
71-nextEntry.sessionFile = path.join(path.dirname(storePath), `${params.newSessionId}.jsonl`);
70+if (typeof params.newSessionFile === "string" && params.newSessionFile) {
71+nextEntry.sessionFile = params.newSessionFile;
72+} else {
73+const storePath = typeof params.storePath === "string" ? params.storePath : rootDir;
74+nextEntry.sessionFile = path.join(
75+path.dirname(storePath),
76+`${params.newSessionId}.jsonl`,
77+);
78+}
7279}
7380params.sessionStore[sessionKey] = nextEntry;
7481if (typeof params.storePath === "string") {
@@ -287,6 +294,76 @@ describe("runMemoryFlushIfNeeded", () => {
287294);
288295});
289296297+it("updates the active preflight run after transcript rotation", async () => {
298+const sessionFile = path.join(rootDir, "session.jsonl");
299+const successorFile = path.join(rootDir, "session-rotated.jsonl");
300+await fs.writeFile(
301+sessionFile,
302+`${JSON.stringify({ message: { role: "user", content: "x".repeat(5_000) } })}\n`,
303+"utf8",
304+);
305+registerMemoryFlushPlanResolver(() => ({
306+softThresholdTokens: 1,
307+forceFlushTranscriptBytes: 1_000_000_000,
308+reserveTokensFloor: 0,
309+prompt: "Pre-compaction memory flush.\nNO_REPLY",
310+systemPrompt: "Write memory to memory/YYYY-MM-DD.md.",
311+relativePath: "memory/2023-11-14.md",
312+}));
313+compactEmbeddedPiSessionMock.mockResolvedValueOnce({
314+ok: true,
315+compacted: true,
316+result: {
317+tokensAfter: 42,
318+sessionId: "session-rotated",
319+sessionFile: successorFile,
320+},
321+});
322+const sessionEntry: SessionEntry = {
323+sessionId: "session",
324+ sessionFile,
325+updatedAt: Date.now(),
326+totalTokensFresh: false,
327+};
328+const sessionStore = { "agent:main:main": sessionEntry };
329+const followupRun = createTestFollowupRun({
330+sessionId: "session",
331+ sessionFile,
332+sessionKey: "agent:main:main",
333+});
334+const updateSessionId = vi.fn();
335+const replyOperation = {
336+abortSignal: new AbortController().signal,
337+setPhase: vi.fn(),
338+ updateSessionId,
339+} as never;
340+341+const entry = await runPreflightCompactionIfNeeded({
342+cfg: { agents: { defaults: { compaction: { memoryFlush: {} } } } },
343+ followupRun,
344+defaultModel: "anthropic/claude-opus-4-6",
345+agentCfgContextTokens: 100,
346+ sessionEntry,
347+ sessionStore,
348+sessionKey: "agent:main:main",
349+storePath: path.join(rootDir, "sessions.json"),
350+isHeartbeat: false,
351+ replyOperation,
352+});
353+354+expect(entry?.sessionId).toBe("session-rotated");
355+expect(entry?.sessionFile).toBe(successorFile);
356+expect(followupRun.run.sessionId).toBe("session-rotated");
357+expect(followupRun.run.sessionFile).toBe(successorFile);
358+expect(updateSessionId).toHaveBeenCalledWith("session-rotated");
359+expect(refreshQueuedFollowupSessionMock).toHaveBeenCalledWith({
360+key: "agent:main:main",
361+previousSessionId: "session",
362+nextSessionId: "session-rotated",
363+nextSessionFile: successorFile,
364+});
365+});
366+290367it("uses configured prompts and stored bootstrap warning signatures", async () => {
291368const sessionEntry: SessionEntry = {
292369sessionId: "session",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。