From 45f7aec156a4f56730bd7fe5bed3d81a79d008e2 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Tue, 2 Jun 2026 11:35:14 +0200 Subject: [PATCH] refactor(gateway): share transcript path comparison --- src/gateway/session-transcript-key.ts | 17 +---------------- src/gateway/session-transcript-path.ts | 16 ++++++++++++++++ src/gateway/sessions-history-http.ts | 20 +++----------------- 3 files changed, 20 insertions(+), 33 deletions(-) create mode 100644 src/gateway/session-transcript-path.ts diff --git a/src/gateway/session-transcript-key.ts b/src/gateway/session-transcript-key.ts index 1415af6fa88a..d3f41019092b 100644 --- a/src/gateway/session-transcript-key.ts +++ b/src/gateway/session-transcript-key.ts @@ -1,11 +1,9 @@ -import fs from "node:fs"; -import path from "node:path"; -import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; import { getRuntimeConfig } from "../config/io.js"; import type { SessionEntry } from "../config/sessions/types.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { normalizeAgentId } from "../routing/session-key.js"; import { resolvePreferredSessionKeyForSessionIdMatches } from "../sessions/session-id-resolution.js"; +import { resolveTranscriptPathForComparison } from "./session-transcript-path.js"; import { loadCombinedSessionStoreForGateway, resolveGatewaySessionStoreTarget, @@ -15,19 +13,6 @@ import { const TRANSCRIPT_SESSION_KEY_CACHE = new Map(); const TRANSCRIPT_SESSION_KEY_CACHE_MAX = 256; -function resolveTranscriptPathForComparison(value: string | undefined): string | undefined { - const trimmed = normalizeOptionalString(value); - if (!trimmed) { - return undefined; - } - const resolved = path.resolve(trimmed); - try { - return fs.realpathSync(resolved); - } catch { - return resolved; - } -} - function sessionKeyMatchesTranscriptPath(params: { cfg: OpenClawConfig; store: Record; diff --git a/src/gateway/session-transcript-path.ts b/src/gateway/session-transcript-path.ts new file mode 100644 index 000000000000..e909a9fb44db --- /dev/null +++ b/src/gateway/session-transcript-path.ts @@ -0,0 +1,16 @@ +import fs from "node:fs"; +import path from "node:path"; +import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce"; + +export function resolveTranscriptPathForComparison(value: string | undefined): string | undefined { + const trimmed = normalizeOptionalString(value); + if (!trimmed) { + return undefined; + } + const resolved = path.resolve(trimmed); + try { + return fs.realpathSync(resolved); + } catch { + return resolved; + } +} diff --git a/src/gateway/sessions-history-http.ts b/src/gateway/sessions-history-http.ts index e5f2176b4418..e66397e1f9a7 100644 --- a/src/gateway/sessions-history-http.ts +++ b/src/gateway/sessions-history-http.ts @@ -1,6 +1,4 @@ -import fs from "node:fs"; import type { IncomingMessage, ServerResponse } from "node:http"; -import path from "node:path"; import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, @@ -30,6 +28,7 @@ import { resolveSessionHistoryTailReadOptions, SessionHistorySseState, } from "./session-history-state.js"; +import { resolveTranscriptPathForComparison } from "./session-transcript-path.js"; import { readRecentSessionMessagesWithStatsAsync, readSessionMessagesAsync, @@ -77,19 +76,6 @@ function resolveLimit(req: IncomingMessage): number | undefined { return Math.min(MAX_SESSION_HISTORY_LIMIT, Math.max(1, value)); } -function canonicalizePath(value: string | undefined): string | undefined { - const trimmed = normalizeOptionalString(value); - if (!trimmed) { - return undefined; - } - const resolved = path.resolve(trimmed); - try { - return fs.realpathSync(resolved); - } catch { - return resolved; - } -} - function sseWrite(res: ServerResponse, event: string, payload: unknown): void { res.write(`event: ${event}\n`); res.write(`data: ${JSON.stringify(payload)}\n\n`); @@ -198,7 +184,7 @@ export async function handleSessionHistoryHttpRequest( entry.sessionFile, target.agentId, ) - .map((candidate) => canonicalizePath(candidate)) + .map((candidate) => resolveTranscriptPathForComparison(candidate)) .filter((candidate): candidate is string => typeof candidate === "string"), ) : new Set(); @@ -306,7 +292,7 @@ export async function handleSessionHistoryHttpRequest( if (!entry?.sessionId) { return; } - const updatePath = canonicalizePath(update.sessionFile); + const updatePath = resolveTranscriptPathForComparison(update.sessionFile); if (!updatePath || !transcriptCandidates.has(updatePath)) { return; }