Skip to content

Commit 2052a3b

Browse files
committed
refactor(sessions): dedupe generated transcript parsing
1 parent 887297e commit 2052a3b

3 files changed

Lines changed: 32 additions & 55 deletions

File tree

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import path from "node:path";
2+
3+
export function extractGeneratedTranscriptSessionId(sessionFile?: string): string | undefined {
4+
const trimmed = sessionFile?.trim();
5+
if (!trimmed) {
6+
return undefined;
7+
}
8+
const base = path.basename(trimmed);
9+
if (!base.endsWith(".jsonl")) {
10+
return undefined;
11+
}
12+
const withoutExt = base.slice(0, -".jsonl".length);
13+
const topicIndex = withoutExt.indexOf("-topic-");
14+
if (topicIndex > 0) {
15+
const topicSessionId = withoutExt.slice(0, topicIndex);
16+
return looksLikeGeneratedSessionId(topicSessionId) ? topicSessionId : undefined;
17+
}
18+
const forkMatch = withoutExt.match(
19+
/^(\d{4}-\d{2}-\d{2}T[\w-]+(?:Z|[+-]\d{2}(?:-\d{2})?)?)_(.+)$/,
20+
);
21+
if (forkMatch?.[2]) {
22+
return looksLikeGeneratedSessionId(forkMatch[2]) ? forkMatch[2] : undefined;
23+
}
24+
return looksLikeGeneratedSessionId(withoutExt) ? withoutExt : undefined;
25+
}
26+
27+
function looksLikeGeneratedSessionId(value: string): boolean {
28+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
29+
}

src/config/sessions/session-accessor.ts

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type { SessionTranscriptUpdate } from "../../sessions/transcript-events.j
1414
import { getRuntimeConfig } from "../io.js";
1515
import type { OpenClawConfig } from "../types.openclaw.js";
1616
import { formatSessionArchiveTimestamp } from "./artifacts.js";
17+
import { extractGeneratedTranscriptSessionId } from "./generated-transcript-session-id.js";
1718
import {
1819
resolveSessionFilePath,
1920
resolveSessionFilePathOptions,
@@ -915,34 +916,6 @@ function classifyGeneratedTranscriptCandidate(
915916
return transcriptSessionId === sessionId ? "current" : "stale";
916917
}
917918

918-
function extractGeneratedTranscriptSessionId(sessionFile?: string): string | undefined {
919-
const trimmed = sessionFile?.trim();
920-
if (!trimmed) {
921-
return undefined;
922-
}
923-
const base = path.basename(trimmed);
924-
if (!base.endsWith(".jsonl")) {
925-
return undefined;
926-
}
927-
const withoutExt = base.slice(0, -".jsonl".length);
928-
const topicIndex = withoutExt.indexOf("-topic-");
929-
if (topicIndex > 0) {
930-
const topicSessionId = withoutExt.slice(0, topicIndex);
931-
return looksLikeGeneratedSessionId(topicSessionId) ? topicSessionId : undefined;
932-
}
933-
const forkMatch = withoutExt.match(
934-
/^(\d{4}-\d{2}-\d{2}T[\w-]+(?:Z|[+-]\d{2}(?:-\d{2})?)?)_(.+)$/,
935-
);
936-
if (forkMatch?.[2]) {
937-
return looksLikeGeneratedSessionId(forkMatch[2]) ? forkMatch[2] : undefined;
938-
}
939-
return looksLikeGeneratedSessionId(withoutExt) ? withoutExt : undefined;
940-
}
941-
942-
function looksLikeGeneratedSessionId(value: string): boolean {
943-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
944-
}
945-
946919
/**
947920
* Persists one logical transcript turn through the current file-backed writer.
948921
* The file implementation resolves/rebinds the transcript file, holds one

src/gateway/session-transcript-files.fs.ts

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
parseSessionArchiveTimestamp,
1010
type SessionArchiveReason,
1111
} from "../config/sessions/artifacts.js";
12+
import { extractGeneratedTranscriptSessionId } from "../config/sessions/generated-transcript-session-id.js";
1213
import {
1314
resolveSessionFilePath,
1415
resolveSessionTranscriptPath,
@@ -106,33 +107,7 @@ function classifySessionTranscriptCandidate(
106107
return transcriptSessionId === sessionId ? "current" : "stale";
107108
}
108109

109-
export function extractGeneratedTranscriptSessionId(sessionFile?: string): string | undefined {
110-
const trimmed = sessionFile?.trim();
111-
if (!trimmed) {
112-
return undefined;
113-
}
114-
const base = path.basename(trimmed);
115-
if (!base.endsWith(".jsonl")) {
116-
return undefined;
117-
}
118-
const withoutExt = base.slice(0, -".jsonl".length);
119-
const topicIndex = withoutExt.indexOf("-topic-");
120-
if (topicIndex > 0) {
121-
const topicSessionId = withoutExt.slice(0, topicIndex);
122-
return looksLikeGeneratedSessionId(topicSessionId) ? topicSessionId : undefined;
123-
}
124-
const forkMatch = withoutExt.match(
125-
/^(\d{4}-\d{2}-\d{2}T[\w-]+(?:Z|[+-]\d{2}(?:-\d{2})?)?)_(.+)$/,
126-
);
127-
if (forkMatch?.[2]) {
128-
return looksLikeGeneratedSessionId(forkMatch[2]) ? forkMatch[2] : undefined;
129-
}
130-
return looksLikeGeneratedSessionId(withoutExt) ? withoutExt : undefined;
131-
}
132-
133-
function looksLikeGeneratedSessionId(value: string): boolean {
134-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
135-
}
110+
export { extractGeneratedTranscriptSessionId };
136111

137112
function canonicalizePathForComparison(filePath: string): string {
138113
const resolved = path.resolve(filePath);

0 commit comments

Comments
 (0)