From 257bb2cb87575ab611ba1069fcac8f440d0f7a56 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 8 May 2026 21:27:53 +0100 Subject: [PATCH] refactor: remove file-only transcript update mode --- packages/memory-host-sdk/src/host/internal.ts | 9 +++++---- src/config/sessions/transcript.test.ts | 4 ++-- src/config/sessions/transcript.ts | 4 ++-- src/gateway/session-utils.ts | 5 +++-- src/gateway/sessions-history-http.test.ts | 2 +- src/plugins/hooks.ts | 4 ++-- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/memory-host-sdk/src/host/internal.ts b/packages/memory-host-sdk/src/host/internal.ts index 1934f724033..5745cdecf8f 100644 --- a/packages/memory-host-sdk/src/host/internal.ts +++ b/packages/memory-host-sdk/src/host/internal.ts @@ -469,10 +469,11 @@ export function chunkMarkdown( * source file positions using a lineMap. Each entry in lineMap gives the * 1-indexed source line for the corresponding 0-indexed content line. * - * This is used for session JSONL files where buildSessionTranscriptEntry() flattens - * messages into a plain-text string before chunking. Without remapping the - * stored line numbers would reference positions in the flattened text rather - * than the original JSONL file. + * This is used for SQLite-backed session transcripts where + * buildSessionTranscriptEntry() flattens messages into a plain-text string + * before chunking. Without remapping the stored line numbers would reference + * positions in the flattened text rather than the original transcript event + * sequence. */ export function remapChunkLines(chunks: MemoryChunk[], lineMap: number[] | undefined): void { if (!lineMap || lineMap.length === 0) { diff --git a/src/config/sessions/transcript.test.ts b/src/config/sessions/transcript.test.ts index 350c200dd67..e47807cf79f 100644 --- a/src/config/sessions/transcript.test.ts +++ b/src/config/sessions/transcript.test.ts @@ -400,13 +400,13 @@ describe("appendAssistantMessageToSessionTranscript", () => { } }); - it("can emit file-only transcript refresh events for exact assistant appends", async () => { + it("can emit signal-only transcript refresh events for exact assistant appends", async () => { await writeTranscriptStore(); const emitSpy = vi.spyOn(transcriptEvents, "emitSessionTranscriptUpdate"); const result = await appendExactAssistantMessageToSessionTranscript({ sessionKey, - updateMode: "file-only", + updateMode: "signal-only", message: createExactAssistantMessage({ text: "Done.", provider: "openclaw", diff --git a/src/config/sessions/transcript.ts b/src/config/sessions/transcript.ts index ed02ffa82b4..8e0cd322342 100644 --- a/src/config/sessions/transcript.ts +++ b/src/config/sessions/transcript.ts @@ -24,7 +24,7 @@ export type SessionTranscriptAppendResult = | { ok: true; sessionFile: string; messageId: string } | { ok: false; reason: string }; -export type SessionTranscriptUpdateMode = "inline" | "file-only" | "none"; +export type SessionTranscriptUpdateMode = "inline" | "signal-only" | "none"; export type SessionTranscriptAssistantMessage = Parameters[0] & { role: "assistant"; @@ -299,7 +299,7 @@ export async function appendExactAssistantMessageToSessionTranscript(params: { messageId, }); break; - case "file-only": + case "signal-only": emitSessionTranscriptUpdate({ agentId, sessionId: entry.sessionId, diff --git a/src/gateway/session-utils.ts b/src/gateway/session-utils.ts index cf6df814eaf..84a57d2f97e 100644 --- a/src/gateway/session-utils.ts +++ b/src/gateway/session-utils.ts @@ -2045,8 +2045,9 @@ export function listSessionsFromStore(params: { * batches of session row builds. This prevents large session row sets from * blocking the event loop during sessions.list requests. * - * The synchronous file I/O in readSessionTitleFieldsFromTranscript (head/tail - * reads for derived titles and last-message previews) is the dominant blocker. + * The synchronous transcript lookup in readSessionTitleFieldsFromTranscript + * (SQLite event scans for derived titles and last-message previews) is the + * dominant blocker. * By yielding every SESSIONS_LIST_YIELD_BATCH_SIZE rows, we keep the event * loop responsive for WebSocket heartbeats, channel I/O, and concurrent RPC. */ diff --git a/src/gateway/sessions-history-http.test.ts b/src/gateway/sessions-history-http.test.ts index 842137a2454..4534b9f6995 100644 --- a/src/gateway/sessions-history-http.test.ts +++ b/src/gateway/sessions-history-http.test.ts @@ -80,7 +80,7 @@ async function appendTranscriptMessage(params: { }): Promise { const appended = await appendExactAssistantMessageToSessionTranscript({ sessionKey: params.sessionKey, - updateMode: params.emitInlineMessage === false ? "file-only" : "inline", + updateMode: params.emitInlineMessage === false ? "signal-only" : "inline", message: params.message, }); expect(appended.ok).toBe(true); diff --git a/src/plugins/hooks.ts b/src/plugins/hooks.ts index a850dbfac69..c1a50908f7d 100644 --- a/src/plugins/hooks.ts +++ b/src/plugins/hooks.ts @@ -1236,8 +1236,8 @@ export function createHookRunner( * session transcripts are appended synchronously. * * Handlers are executed sequentially in priority order (higher first). - * If any handler returns { block: true }, the message is NOT written - * to the session JSONL and we return immediately. + * If any handler returns { block: true }, the message is NOT persisted + * to the SQLite transcript and we return immediately. * If a handler returns { message }, the modified message replaces the * original for subsequent handlers and the final write. */