mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-22 14:48:11 +00:00
refactor(sessions): dedupe generated transcript parsing
This commit is contained in:
29
src/config/sessions/generated-transcript-session-id.ts
Normal file
29
src/config/sessions/generated-transcript-session-id.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import path from "node:path";
|
||||
|
||||
export function extractGeneratedTranscriptSessionId(sessionFile?: string): string | undefined {
|
||||
const trimmed = sessionFile?.trim();
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
const base = path.basename(trimmed);
|
||||
if (!base.endsWith(".jsonl")) {
|
||||
return undefined;
|
||||
}
|
||||
const withoutExt = base.slice(0, -".jsonl".length);
|
||||
const topicIndex = withoutExt.indexOf("-topic-");
|
||||
if (topicIndex > 0) {
|
||||
const topicSessionId = withoutExt.slice(0, topicIndex);
|
||||
return looksLikeGeneratedSessionId(topicSessionId) ? topicSessionId : undefined;
|
||||
}
|
||||
const forkMatch = withoutExt.match(
|
||||
/^(\d{4}-\d{2}-\d{2}T[\w-]+(?:Z|[+-]\d{2}(?:-\d{2})?)?)_(.+)$/,
|
||||
);
|
||||
if (forkMatch?.[2]) {
|
||||
return looksLikeGeneratedSessionId(forkMatch[2]) ? forkMatch[2] : undefined;
|
||||
}
|
||||
return looksLikeGeneratedSessionId(withoutExt) ? withoutExt : undefined;
|
||||
}
|
||||
|
||||
function looksLikeGeneratedSessionId(value: string): boolean {
|
||||
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);
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import type { SessionTranscriptUpdate } from "../../sessions/transcript-events.j
|
||||
import { getRuntimeConfig } from "../io.js";
|
||||
import type { OpenClawConfig } from "../types.openclaw.js";
|
||||
import { formatSessionArchiveTimestamp } from "./artifacts.js";
|
||||
import { extractGeneratedTranscriptSessionId } from "./generated-transcript-session-id.js";
|
||||
import {
|
||||
resolveSessionFilePath,
|
||||
resolveSessionFilePathOptions,
|
||||
@@ -915,34 +916,6 @@ function classifyGeneratedTranscriptCandidate(
|
||||
return transcriptSessionId === sessionId ? "current" : "stale";
|
||||
}
|
||||
|
||||
function extractGeneratedTranscriptSessionId(sessionFile?: string): string | undefined {
|
||||
const trimmed = sessionFile?.trim();
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
const base = path.basename(trimmed);
|
||||
if (!base.endsWith(".jsonl")) {
|
||||
return undefined;
|
||||
}
|
||||
const withoutExt = base.slice(0, -".jsonl".length);
|
||||
const topicIndex = withoutExt.indexOf("-topic-");
|
||||
if (topicIndex > 0) {
|
||||
const topicSessionId = withoutExt.slice(0, topicIndex);
|
||||
return looksLikeGeneratedSessionId(topicSessionId) ? topicSessionId : undefined;
|
||||
}
|
||||
const forkMatch = withoutExt.match(
|
||||
/^(\d{4}-\d{2}-\d{2}T[\w-]+(?:Z|[+-]\d{2}(?:-\d{2})?)?)_(.+)$/,
|
||||
);
|
||||
if (forkMatch?.[2]) {
|
||||
return looksLikeGeneratedSessionId(forkMatch[2]) ? forkMatch[2] : undefined;
|
||||
}
|
||||
return looksLikeGeneratedSessionId(withoutExt) ? withoutExt : undefined;
|
||||
}
|
||||
|
||||
function looksLikeGeneratedSessionId(value: string): boolean {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists one logical transcript turn through the current file-backed writer.
|
||||
* The file implementation resolves/rebinds the transcript file, holds one
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
parseSessionArchiveTimestamp,
|
||||
type SessionArchiveReason,
|
||||
} from "../config/sessions/artifacts.js";
|
||||
import { extractGeneratedTranscriptSessionId } from "../config/sessions/generated-transcript-session-id.js";
|
||||
import {
|
||||
resolveSessionFilePath,
|
||||
resolveSessionTranscriptPath,
|
||||
@@ -106,33 +107,7 @@ function classifySessionTranscriptCandidate(
|
||||
return transcriptSessionId === sessionId ? "current" : "stale";
|
||||
}
|
||||
|
||||
export function extractGeneratedTranscriptSessionId(sessionFile?: string): string | undefined {
|
||||
const trimmed = sessionFile?.trim();
|
||||
if (!trimmed) {
|
||||
return undefined;
|
||||
}
|
||||
const base = path.basename(trimmed);
|
||||
if (!base.endsWith(".jsonl")) {
|
||||
return undefined;
|
||||
}
|
||||
const withoutExt = base.slice(0, -".jsonl".length);
|
||||
const topicIndex = withoutExt.indexOf("-topic-");
|
||||
if (topicIndex > 0) {
|
||||
const topicSessionId = withoutExt.slice(0, topicIndex);
|
||||
return looksLikeGeneratedSessionId(topicSessionId) ? topicSessionId : undefined;
|
||||
}
|
||||
const forkMatch = withoutExt.match(
|
||||
/^(\d{4}-\d{2}-\d{2}T[\w-]+(?:Z|[+-]\d{2}(?:-\d{2})?)?)_(.+)$/,
|
||||
);
|
||||
if (forkMatch?.[2]) {
|
||||
return looksLikeGeneratedSessionId(forkMatch[2]) ? forkMatch[2] : undefined;
|
||||
}
|
||||
return looksLikeGeneratedSessionId(withoutExt) ? withoutExt : undefined;
|
||||
}
|
||||
|
||||
function looksLikeGeneratedSessionId(value: string): boolean {
|
||||
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);
|
||||
}
|
||||
export { extractGeneratedTranscriptSessionId };
|
||||
|
||||
function canonicalizePathForComparison(filePath: string): string {
|
||||
const resolved = path.resolve(filePath);
|
||||
|
||||
Reference in New Issue
Block a user