diff --git a/extensions/memory-core/src/memory/index.test.ts b/extensions/memory-core/src/memory/index.test.ts index 31ad28e49902..9f2224eb1222 100644 --- a/extensions/memory-core/src/memory/index.test.ts +++ b/extensions/memory-core/src/memory/index.test.ts @@ -7,7 +7,10 @@ import type { DatabaseSync } from "node:sqlite"; import { clearMemoryEmbeddingProviders as clearRegistry } from "openclaw/plugin-sdk/memory-core-host-engine-embeddings"; import { hashText } from "openclaw/plugin-sdk/memory-core-host-engine-storage"; import { resolveSessionTranscriptsDirForAgent } from "openclaw/plugin-sdk/memory-core-host-runtime-core"; -import { upsertSessionEntry } from "openclaw/plugin-sdk/session-store-runtime"; +import { + formatSqliteSessionFileMarker, + upsertSessionEntry, +} from "openclaw/plugin-sdk/session-store-runtime"; import { appendSessionTranscriptMessageByIdentity } from "openclaw/plugin-sdk/session-transcript-runtime"; import { resolveOpenClawAgentSqlitePath } from "openclaw/plugin-sdk/sqlite-runtime"; import { @@ -431,18 +434,23 @@ describe("memory index", () => { const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); const storePath = path.join(sessionsDir, "sessions.json"); const sessionKey = params.sessionKey ?? `agent:main:memory:${params.sessionId}`; - const timestamps = params.messages - .map((message) => - typeof message.timestamp === "number" ? message.timestamp : Date.parse(message.timestamp), - ) - .filter((timestamp) => Number.isFinite(timestamp)); - const updatedAt = timestamps.length > 0 ? Math.max(...timestamps) : Date.now(); + // Message timestamps are behavioral inputs; entry freshness only keeps the + // fixture out of real session-retention maintenance as wall time advances. + const updatedAt = Date.now(); await fs.mkdir(sessionsDir, { recursive: true }); await upsertSessionEntry({ agentId: "main", sessionKey, storePath, - entry: { sessionId: params.sessionId, updatedAt }, + entry: { + sessionId: params.sessionId, + sessionFile: formatSqliteSessionFileMarker({ + agentId: "main", + sessionId: params.sessionId, + storePath, + }), + updatedAt, + }, }); for (const message of params.messages) { await appendSessionTranscriptMessageByIdentity({ @@ -2989,10 +2997,16 @@ describe("memory index", () => { const stateDirName = ".state-status-dirty-test"; setMemoryIndexStateDir(path.join(workspaceDir, stateDirName)); try { - const sessionsDir = resolveSessionTranscriptsDirForAgent("main"); - await fs.mkdir(sessionsDir, { recursive: true }); - const transcriptPath = path.join(sessionsDir, "status-dirty-test.jsonl"); - await fs.writeFile(transcriptPath, JSON.stringify({ type: "test", ts: 1 }) + "\n"); + await seedMemoryIndexSessionTranscript({ + sessionId: "status-dirty-test", + messages: [ + { + role: "user", + timestamp: 1, + content: "Unindexed session transcript.", + }, + ], + }); const manager = await getFreshManager(cfg, "status"); managersForCleanup.add(manager); diff --git a/extensions/memory-core/src/memory/manager-sync-yield.test.ts b/extensions/memory-core/src/memory/manager-sync-yield.test.ts index a421345748e3..1706559783c9 100644 --- a/extensions/memory-core/src/memory/manager-sync-yield.test.ts +++ b/extensions/memory-core/src/memory/manager-sync-yield.test.ts @@ -44,9 +44,12 @@ vi.mock("undici", async () => { }; }); -vi.mock("openclaw/plugin-sdk/memory-core-host-engine-qmd", () => { +vi.mock("openclaw/plugin-sdk/memory-core-host-engine-qmd", async (importOriginal) => { + const actual = + await importOriginal(); const basename = (filePath: string) => filePath.split(/[\\/]/).pop() ?? filePath; return { + ...actual, buildSessionEntry: buildSessionEntryMock, isSessionArchiveArtifactName: (fileName: string) => /\.jsonl\.(reset|deleted)\./.test(fileName), isUsageCountedSessionTranscriptFileName: (fileName: string) => fileName.endsWith(".jsonl"), diff --git a/extensions/memory-core/src/memory/qmd-manager.test.ts b/extensions/memory-core/src/memory/qmd-manager.test.ts index 305227fe45b6..30deb8db2625 100644 --- a/extensions/memory-core/src/memory/qmd-manager.test.ts +++ b/extensions/memory-core/src/memory/qmd-manager.test.ts @@ -204,7 +204,10 @@ import { resolveMemoryBackendConfig, } from "openclaw/plugin-sdk/memory-core-host-engine-storage"; import { MAX_TIMER_TIMEOUT_MS } from "openclaw/plugin-sdk/number-runtime"; -import { upsertSessionEntry } from "openclaw/plugin-sdk/session-store-runtime"; +import { + formatSqliteSessionFileMarker, + upsertSessionEntry, +} from "openclaw/plugin-sdk/session-store-runtime"; import { formatSessionTranscriptMemoryHitKey } from "openclaw/plugin-sdk/session-transcript-hit"; import { appendSessionTranscriptMessageByIdentity } from "openclaw/plugin-sdk/session-transcript-runtime"; import { closeOpenClawAgentDatabasesForTest } from "openclaw/plugin-sdk/sqlite-runtime-testing"; @@ -240,13 +243,23 @@ async function seedQmdSessionTranscript(params: { const timestamp = typeof params.timestamp === "number" ? params.timestamp - : Date.parse(params.timestamp ?? "2026-04-07T15:25:04.113Z"); + : params.timestamp + ? Date.parse(params.timestamp) + : Date.now(); await fs.mkdir(sessionsDir, { recursive: true }); await upsertSessionEntry({ agentId: params.agentId, sessionKey, storePath, - entry: { sessionId: params.sessionId, updatedAt: timestamp }, + entry: { + sessionId: params.sessionId, + sessionFile: formatSqliteSessionFileMarker({ + agentId: params.agentId, + sessionId: params.sessionId, + storePath, + }), + updatedAt: timestamp, + }, }); await appendSessionTranscriptMessageByIdentity({ agentId: params.agentId,