mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-07 02:22:46 +00:00
fix(sessions): rewrite migrated transcript paths
This commit is contained in:
@@ -479,15 +479,9 @@ function assertSessionMetadataMigrated(stateDir) {
|
||||
const main = store["agent:main:main"];
|
||||
const direct = store["agent:main:+15551234567"];
|
||||
const group = store["agent:main:slack:channel:cupgrade"];
|
||||
assert(main?.sessionId === LEGACY_SESSION_MAIN_ID, "main legacy session row missing from SQLite");
|
||||
assert(
|
||||
direct?.sessionId === LEGACY_SESSION_DIRECT_ID,
|
||||
"direct legacy session row missing from SQLite",
|
||||
);
|
||||
assert(
|
||||
group?.sessionId === LEGACY_SESSION_GROUP_ID,
|
||||
"channel legacy session row missing from SQLite",
|
||||
);
|
||||
assert(main?.sessionId === LEGACY_SESSION_MAIN_ID, "main legacy session row missing");
|
||||
assert(direct?.sessionId === LEGACY_SESSION_DIRECT_ID, "direct legacy session row missing");
|
||||
assert(group?.sessionId === LEGACY_SESSION_GROUP_ID, "channel legacy session row missing");
|
||||
assert(
|
||||
main?.sessionFile === path.join(agentSessionsDir, `${LEGACY_SESSION_MAIN_ID}.jsonl`),
|
||||
"main legacy session row still points at the old sessions directory",
|
||||
@@ -506,7 +500,7 @@ function assertSessionMetadataMigrated(stateDir) {
|
||||
);
|
||||
assert(
|
||||
main.skillsSnapshot?.resolvedSkills === undefined,
|
||||
"heavy resolvedSkills cache was persisted into SQLite session metadata",
|
||||
"heavy resolvedSkills cache was persisted into migrated session metadata",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -629,7 +629,7 @@ describe("doctor legacy state migrations", () => {
|
||||
result: Awaited<ReturnType<typeof runLegacyStateMigrations>>;
|
||||
targetDir: string;
|
||||
legacySessionsDir: string;
|
||||
store: Record<string, { sessionId: string }>;
|
||||
store: Record<string, { sessionId: string; sessionFile?: string }>;
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
@@ -638,8 +638,12 @@ describe("doctor legacy state migrations", () => {
|
||||
const legacySessionsDir = writeLegacySessionsFixture({
|
||||
root,
|
||||
sessions: {
|
||||
"+1555": { sessionId: "a", updatedAt: 10 },
|
||||
"+1666": { sessionId: "b", updatedAt: 20 },
|
||||
"+1555": {
|
||||
sessionId: "a",
|
||||
sessionFile: path.join(root, "sessions", "a.jsonl"),
|
||||
updatedAt: 10,
|
||||
},
|
||||
"+1666": { sessionId: "b", sessionFile: "b.jsonl", updatedAt: 20 },
|
||||
"slack:channel:C123": { sessionId: "c", updatedAt: 30 },
|
||||
"group:abc": { sessionId: "d", updatedAt: 40 },
|
||||
"subagent:xyz": { sessionId: "e", updatedAt: 50 },
|
||||
@@ -661,7 +665,7 @@ describe("doctor legacy state migrations", () => {
|
||||
const targetDir = path.join(root, "agents", "main", "sessions");
|
||||
const store = JSON.parse(
|
||||
fs.readFileSync(path.join(targetDir, "sessions.json"), "utf-8"),
|
||||
) as Record<string, { sessionId: string }>;
|
||||
) as Record<string, { sessionId: string; sessionFile?: string }>;
|
||||
|
||||
migratedLegacySessionsCase = { result, targetDir, legacySessionsDir, store };
|
||||
});
|
||||
@@ -676,6 +680,8 @@ describe("doctor legacy state migrations", () => {
|
||||
expect(store["agent:main:main"]?.sessionId).toBe("b");
|
||||
expect(store["agent:main:+1555"]?.sessionId).toBe("a");
|
||||
expect(store["agent:main:+1666"]?.sessionId).toBe("b");
|
||||
expect(store["agent:main:+1555"]?.sessionFile).toBe(path.join(targetDir, "a.jsonl"));
|
||||
expect(store["agent:main:+1666"]?.sessionFile).toBe(path.join(targetDir, "b.jsonl"));
|
||||
expect(store["+1555"]).toBeUndefined();
|
||||
expect(store["+1666"]).toBeUndefined();
|
||||
expect(store["agent:main:slack:channel:c123"]?.sessionId).toBe("c");
|
||||
|
||||
@@ -2878,6 +2878,7 @@ async function migrateLegacySessions(
|
||||
return { changes, warnings };
|
||||
}
|
||||
|
||||
const movedSessionFiles = new Map<string, string>();
|
||||
const entries = safeReadDir(detected.sessions.legacyDir);
|
||||
for (const entry of entries) {
|
||||
if (!entry.isFile()) {
|
||||
@@ -2887,18 +2888,54 @@ async function migrateLegacySessions(
|
||||
continue;
|
||||
}
|
||||
const from = path.join(detected.sessions.legacyDir, entry.name);
|
||||
const to = path.join(detected.sessions.targetDir, entry.name);
|
||||
let to = path.join(detected.sessions.targetDir, entry.name);
|
||||
if (fileExists(to)) {
|
||||
continue;
|
||||
const parsed = path.parse(entry.name);
|
||||
to = path.join(detected.sessions.targetDir, `${parsed.name}.legacy-${now()}${parsed.ext}`);
|
||||
}
|
||||
try {
|
||||
fs.renameSync(from, to);
|
||||
movedSessionFiles.set(path.resolve(from), to);
|
||||
changes.push(`Moved ${entry.name} → agents/${detected.targetAgentId}/sessions`);
|
||||
} catch (err) {
|
||||
warnings.push(`Failed moving ${from}: ${String(err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (movedSessionFiles.size > 0) {
|
||||
let rewroteSessionFiles = false;
|
||||
for (const entry of Object.values(merged)) {
|
||||
const rawSessionFile = entry.sessionFile;
|
||||
const legacySessionFile =
|
||||
typeof rawSessionFile === "string"
|
||||
? path.resolve(detected.sessions.legacyDir, rawSessionFile)
|
||||
: typeof entry.sessionId === "string"
|
||||
? path.join(detected.sessions.legacyDir, `${entry.sessionId}.jsonl`)
|
||||
: undefined;
|
||||
const movedSessionFile = legacySessionFile
|
||||
? movedSessionFiles.get(path.resolve(legacySessionFile))
|
||||
: undefined;
|
||||
if (!movedSessionFile) {
|
||||
continue;
|
||||
}
|
||||
entry.sessionFile = movedSessionFile;
|
||||
rewroteSessionFiles = true;
|
||||
}
|
||||
if (rewroteSessionFiles) {
|
||||
const normalized: Record<string, SessionEntry> = {};
|
||||
for (const [key, entry] of Object.entries(merged)) {
|
||||
const normalizedEntry = normalizeSessionEntry(entry);
|
||||
if (normalizedEntry) {
|
||||
normalized[key] = normalizedEntry;
|
||||
}
|
||||
}
|
||||
await saveSessionStore(detected.sessions.targetStorePath, normalized, {
|
||||
skipMaintenance: true,
|
||||
});
|
||||
changes.push("Rewrote migrated session transcript paths");
|
||||
}
|
||||
}
|
||||
|
||||
if (legacyParsed.ok && targetReadable) {
|
||||
try {
|
||||
if (fileExists(detected.sessions.legacyStorePath)) {
|
||||
|
||||
Reference in New Issue
Block a user