mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 05:20:22 +00:00
fix: keep session transcript pointers fresh after compaction (#50688)
Co-authored-by: Frank Yang <frank.ekn@gmail.com>
This commit is contained in:
committed by
GitHub
parent
dd132ea77b
commit
d2e8ed3632
@@ -15,16 +15,6 @@ const runEmbeddedPiAgentMock = vi.fn();
|
||||
const runCliAgentMock = vi.fn();
|
||||
const runWithModelFallbackMock = vi.fn();
|
||||
const runtimeErrorMock = vi.fn();
|
||||
const runMemoryFlushIfNeededMock = vi.hoisted(() =>
|
||||
vi.fn(async ({ sessionEntry }) => sessionEntry),
|
||||
);
|
||||
const createReplyMediaPathNormalizerMock = vi.hoisted(() =>
|
||||
vi.fn(
|
||||
(_params?: unknown) =>
|
||||
async <T>(payload: T) =>
|
||||
payload,
|
||||
),
|
||||
);
|
||||
|
||||
vi.mock("../../agents/model-fallback.js", () => ({
|
||||
runWithModelFallback: (params: {
|
||||
@@ -68,14 +58,6 @@ vi.mock("../../runtime.js", async () => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./agent-runner-memory.runtime.js", () => ({
|
||||
runMemoryFlushIfNeeded: (params: unknown) => runMemoryFlushIfNeededMock(params),
|
||||
}));
|
||||
|
||||
vi.mock("./reply-media-paths.runtime.js", () => ({
|
||||
createReplyMediaPathNormalizer: (params: unknown) => createReplyMediaPathNormalizerMock(params),
|
||||
}));
|
||||
|
||||
vi.mock("./queue.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("./queue.js")>("./queue.js");
|
||||
return {
|
||||
@@ -103,40 +85,10 @@ type RunWithModelFallbackParams = {
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
vi.useRealTimers();
|
||||
vi.clearAllTimers();
|
||||
runEmbeddedPiAgentMock.mockClear();
|
||||
runCliAgentMock.mockClear();
|
||||
runWithModelFallbackMock.mockClear();
|
||||
runtimeErrorMock.mockClear();
|
||||
runMemoryFlushIfNeededMock.mockClear();
|
||||
runMemoryFlushIfNeededMock.mockImplementation(
|
||||
async ({
|
||||
sessionEntry,
|
||||
followupRun,
|
||||
}: {
|
||||
sessionEntry?: SessionEntry;
|
||||
followupRun: FollowupRun;
|
||||
}) => {
|
||||
if (!sessionEntry || (sessionEntry.totalTokens ?? 0) < 1_000_000) {
|
||||
return sessionEntry;
|
||||
}
|
||||
await runWithModelFallbackMock({
|
||||
provider: followupRun.run.provider,
|
||||
model: followupRun.run.model,
|
||||
run: async (provider: string, model: string) =>
|
||||
await runEmbeddedPiAgentMock({
|
||||
provider,
|
||||
model,
|
||||
prompt: "Pre-compaction memory flush.",
|
||||
enforceFinalTag: provider.includes("gemini") ? true : undefined,
|
||||
}),
|
||||
});
|
||||
return sessionEntry;
|
||||
},
|
||||
);
|
||||
createReplyMediaPathNormalizerMock.mockClear();
|
||||
createReplyMediaPathNormalizerMock.mockImplementation(() => async (payload) => payload);
|
||||
loadCronStoreMock.mockClear();
|
||||
// Default: no cron jobs in store.
|
||||
loadCronStoreMock.mockResolvedValue({ version: 1, jobs: [] });
|
||||
@@ -153,7 +105,6 @@ beforeEach(() => {
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
resetSystemEventsForTest();
|
||||
});
|
||||
@@ -388,6 +339,11 @@ describe("runReplyAgent auto-compaction token update", () => {
|
||||
);
|
||||
}
|
||||
|
||||
async function normalizeComparablePath(filePath: string): Promise<string> {
|
||||
const parent = await fs.realpath(path.dirname(filePath)).catch(() => path.dirname(filePath));
|
||||
return path.join(parent, path.basename(filePath));
|
||||
}
|
||||
|
||||
function createBaseRun(params: {
|
||||
storePath: string;
|
||||
sessionEntry: Record<string, unknown>;
|
||||
@@ -436,6 +392,7 @@ describe("runReplyAgent auto-compaction token update", () => {
|
||||
const sessionKey = "main";
|
||||
const sessionEntry = {
|
||||
sessionId: "session",
|
||||
sessionFile: path.join(tmp, "session.jsonl"),
|
||||
updatedAt: Date.now(),
|
||||
totalTokens: 181_000,
|
||||
compactionCount: 0,
|
||||
@@ -524,6 +481,7 @@ describe("runReplyAgent auto-compaction token update", () => {
|
||||
payloads: [{ text: "done" }],
|
||||
meta: {
|
||||
agentMeta: {
|
||||
sessionId: "session-rotated",
|
||||
usage: { input: 190_000, output: 8_000, total: 198_000 },
|
||||
lastCallUsage: { input: 10_000, output: 3_000, total: 13_000 },
|
||||
compactionCount: 2,
|
||||
@@ -568,6 +526,10 @@ describe("runReplyAgent auto-compaction token update", () => {
|
||||
const stored = JSON.parse(await fs.readFile(storePath, "utf-8"));
|
||||
expect(stored[sessionKey].totalTokens).toBe(10_000);
|
||||
expect(stored[sessionKey].compactionCount).toBe(2);
|
||||
expect(stored[sessionKey].sessionId).toBe("session-rotated");
|
||||
expect(await normalizeComparablePath(stored[sessionKey].sessionFile)).toBe(
|
||||
await normalizeComparablePath(path.join(tmp, "session-rotated.jsonl")),
|
||||
);
|
||||
});
|
||||
|
||||
it("accumulates compactions across fallback attempts without double-counting a single attempt", async () => {
|
||||
|
||||
Reference in New Issue
Block a user