





















@@ -433,6 +433,33 @@ function cloneCheckpointSessionEntry(params: {
433433};
434434}
435435436+function resolveCheckpointForkSource(
437+checkpoint: NonNullable<ReturnType<typeof getSessionCompactionCheckpoint>>,
438+): { sourceFile: string; sourceLeafId?: string; totalTokens?: number } | null {
439+const preCompactionFile = checkpoint.preCompaction.sessionFile?.trim();
440+if (preCompactionFile) {
441+return {
442+sourceFile: preCompactionFile,
443+sourceLeafId: checkpoint.preCompaction.leafId,
444+totalTokens: checkpoint.tokensBefore,
445+};
446+}
447+const postCompactionFile = checkpoint.postCompaction.sessionFile?.trim();
448+if (!postCompactionFile) {
449+return null;
450+}
451+const postCompactionLeafId =
452+checkpoint.postCompaction.leafId ?? checkpoint.postCompaction.entryId;
453+if (!postCompactionLeafId) {
454+return null;
455+}
456+return {
457+sourceFile: postCompactionFile,
458+sourceLeafId: postCompactionLeafId,
459+totalTokens: checkpoint.tokensAfter,
460+};
461+}
462+436463function isAgentMainSessionKey(cfg: OpenClawConfig, sessionKey: string): boolean {
437464const parsed = parseAgentSessionKey(sessionKey);
438465if (!parsed) {
@@ -1555,7 +1582,8 @@ export const sessionsHandlers: GatewayRequestHandlers = {
15551582return;
15561583}
15571584const checkpoint = getSessionCompactionCheckpoint({ entry, checkpointId });
1558-if (!checkpoint?.preCompaction.sessionFile) {
1585+const forkSource = checkpoint ? resolveCheckpointForkSource(checkpoint) : null;
1586+if (!checkpoint || !forkSource) {
15591587respond(
15601588false,
15611589undefined,
@@ -1564,8 +1592,9 @@ export const sessionsHandlers: GatewayRequestHandlers = {
15641592return;
15651593}
15661594const branchedSession = await forkCompactionCheckpointTranscriptAsync({
1567-sourceFile: checkpoint.preCompaction.sessionFile,
1568-sessionDir: path.dirname(checkpoint.preCompaction.sessionFile),
1595+sourceFile: forkSource.sourceFile,
1596+sourceLeafId: forkSource.sourceLeafId,
1597+sessionDir: path.dirname(forkSource.sourceFile),
15691598});
15701599if (!branchedSession?.sessionFile) {
15711600respond(
@@ -1583,7 +1612,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
15831612nextSessionFile: branchedSession.sessionFile,
15841613 label,
15851614parentSessionKey: canonicalKey,
1586-totalTokens: checkpoint.tokensBefore,
1615+totalTokens: forkSource.totalTokens,
15871616});
1588161715891618await updateSessionStore(target.storePath, (store) => {
@@ -1654,7 +1683,8 @@ export const sessionsHandlers: GatewayRequestHandlers = {
16541683return;
16551684}
16561685const checkpoint = getSessionCompactionCheckpoint({ entry, checkpointId });
1657-if (!checkpoint?.preCompaction.sessionFile) {
1686+const forkSource = checkpoint ? resolveCheckpointForkSource(checkpoint) : null;
1687+if (!checkpoint || !forkSource) {
16581688respond(
16591689false,
16601690undefined,
@@ -1677,8 +1707,9 @@ export const sessionsHandlers: GatewayRequestHandlers = {
16771707}
1678170816791709const restoredSession = await forkCompactionCheckpointTranscriptAsync({
1680-sourceFile: checkpoint.preCompaction.sessionFile,
1681-sessionDir: path.dirname(checkpoint.preCompaction.sessionFile),
1710+sourceFile: forkSource.sourceFile,
1711+sourceLeafId: forkSource.sourceLeafId,
1712+sessionDir: path.dirname(forkSource.sourceFile),
16821713});
16831714if (!restoredSession?.sessionFile) {
16841715respond(
@@ -1692,7 +1723,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
16921723currentEntry: entry,
16931724nextSessionId: restoredSession.sessionId,
16941725nextSessionFile: restoredSession.sessionFile,
1695-totalTokens: checkpoint.tokensBefore,
1726+totalTokens: forkSource.totalTokens,
16961727preserveCompactionCheckpoints: true,
16971728});
16981729此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。