mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 20:35:39 -06:00
perf(usage): bound session log retention
This commit is contained in:
@@ -2753,4 +2753,28 @@ example
|
||||
loadSessionLogs({ sessionFile, limit: Number.POSITIVE_INFINITY }),
|
||||
).resolves.toEqual([]);
|
||||
});
|
||||
|
||||
it("keeps the latest logs when transcript timestamps are out of order", async () => {
|
||||
const root = await makeSessionCostRoot("session-logs-unsorted-limit");
|
||||
const sessionFile = path.join(root, "session.jsonl");
|
||||
const entries = [
|
||||
["2026-02-12T10:03:00.000Z", "third"],
|
||||
["2026-02-12T10:01:00.000Z", "first"],
|
||||
["2026-02-12T10:04:00.000Z", "fourth"],
|
||||
["2026-02-12T10:02:00.000Z", "second"],
|
||||
].map(([timestamp, content]) => ({
|
||||
type: "message",
|
||||
timestamp,
|
||||
message: { role: "user", content },
|
||||
}));
|
||||
await fs.writeFile(
|
||||
sessionFile,
|
||||
entries.map((entry) => JSON.stringify(entry)).join("\n"),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const logs = await loadSessionLogs({ sessionFile, limit: 2 });
|
||||
|
||||
expect(logs?.map((log) => log.content)).toEqual(["third", "fourth"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2525,6 +2525,8 @@ export async function loadSessionLogs(params: {
|
||||
}
|
||||
}
|
||||
const limit = params.limit ?? 50;
|
||||
const boundedLimit = Number.isInteger(limit);
|
||||
const retentionLimit = limit * 2;
|
||||
const resolveCost = createUsageCostResolver(params.config);
|
||||
|
||||
for await (const parsed of readJsonlRecords(sessionFile)) {
|
||||
@@ -2656,15 +2658,25 @@ export async function loadSessionLogs(params: {
|
||||
tokens,
|
||||
cost,
|
||||
});
|
||||
// Timestamps can arrive out of order, so keep a bounded sorted window instead
|
||||
// of relying on transcript append order or retaining the whole file.
|
||||
if (boundedLimit && logs.length > retentionLimit) {
|
||||
logs.sort((a, b) => a.timestamp - b.timestamp);
|
||||
logs.splice(0, logs.length - limit);
|
||||
}
|
||||
} catch {
|
||||
// Ignore malformed lines
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by timestamp and limit
|
||||
const sortedLogs = logs.toSorted((a, b) => a.timestamp - b.timestamp);
|
||||
if (boundedLimit) {
|
||||
logs.sort((a, b) => a.timestamp - b.timestamp);
|
||||
return logs.length > limit ? logs.slice(-limit) : logs;
|
||||
}
|
||||
|
||||
// Return most recent logs
|
||||
const sortedLogs = logs.toSorted((a, b) => a.timestamp - b.timestamp);
|
||||
if (sortedLogs.length > limit) {
|
||||
return sortedLogs.slice(-limit);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user