mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(memory-core): keep daily ingestion outside session repair (#93389)
* fix(memory-core): clear daily-ingestion sqlite namespace on dreaming repair repairDreamingArtifacts() cleared the dreaming-session-ingestion-files and dreaming-session-ingestion-seen namespaces but not the migrated dreaming-daily-ingestion namespace. After #92020 taught auditDreamingArtifacts() to treat all three ingestion namespaces as ingestion state, the repair path became asymmetric: the memory status --fix re-audit still reported sessionIngestionExists=true from the surviving daily rows, and the daily ingestion bookkeeping leaked past repair so daily memory files were not re-ingested on the next sweep. Clear DREAMING_DAILY_INGESTION_NAMESPACE alongside the session files/seen namespaces so repair fully resets dreaming ingestion state, matching the audit. * chore: retrigger CI for real behavior proof check * fix(memory-core): keep daily ingestion outside session repair Co-authored-by: Vincent Koc <vincentkoc@ieee.org> Co-authored-by: Alix-007 <li.long15@xydigit.com> --------- Co-authored-by: Peter Steinberger <steipete@gmail.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
co-authored by
Peter Steinberger
Vincent Koc
parent
673b87a403
commit
962d1096d4
@@ -199,6 +199,10 @@ describe("dreaming artifact repair", () => {
|
||||
}),
|
||||
]);
|
||||
|
||||
await expect(
|
||||
auditDreamingArtifacts({ workspaceDir }).then((audit) => audit.sessionIngestionExists),
|
||||
).resolves.toBe(true);
|
||||
|
||||
const repair = await repairDreamingArtifacts({ workspaceDir });
|
||||
|
||||
expect(repair.archivedSessionCorpus).toBe(true);
|
||||
@@ -214,6 +218,41 @@ describe("dreaming artifact repair", () => {
|
||||
workspaceDir,
|
||||
}),
|
||||
).resolves.toEqual([]);
|
||||
await expect(
|
||||
auditDreamingArtifacts({ workspaceDir }).then((audit) => audit.sessionIngestionExists),
|
||||
).resolves.toBe(false);
|
||||
});
|
||||
|
||||
it("preserves sqlite daily ingestion state when archiving session corpus", async () => {
|
||||
const workspaceDir = await createWorkspace();
|
||||
const sessionCorpusDir = path.join(workspaceDir, "memory", ".dreams", "session-corpus");
|
||||
await fs.mkdir(sessionCorpusDir, { recursive: true });
|
||||
await fs.writeFile(path.join(sessionCorpusDir, "2026-04-11.txt"), "corpus\n", "utf-8");
|
||||
await writeMemoryCoreWorkspaceEntries({
|
||||
namespace: DREAMING_DAILY_INGESTION_NAMESPACE,
|
||||
workspaceDir,
|
||||
entries: [
|
||||
{
|
||||
key: "2026-06-10",
|
||||
value: { ingestedAt: 1_000, lastDreamingDayIngested: "2026-06-10" },
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const repair = await repairDreamingArtifacts({ workspaceDir });
|
||||
|
||||
expect(repair.archivedSessionCorpus).toBe(true);
|
||||
await expect(
|
||||
readMemoryCoreWorkspaceEntries({
|
||||
namespace: DREAMING_DAILY_INGESTION_NAMESPACE,
|
||||
workspaceDir,
|
||||
}),
|
||||
).resolves.toEqual([
|
||||
{
|
||||
key: "2026-06-10",
|
||||
value: { ingestedAt: 1_000, lastDreamingDayIngested: "2026-06-10" },
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it("reports ingestion state present from SQLite when legacy JSON is absent", async () => {
|
||||
@@ -235,7 +274,7 @@ describe("dreaming artifact repair", () => {
|
||||
expect(audit.sessionIngestionExists).toBe(true);
|
||||
});
|
||||
|
||||
it("reports ingestion state present from SQLite daily namespace", async () => {
|
||||
it("does not report session ingestion from the SQLite daily namespace", async () => {
|
||||
const workspaceDir = await createWorkspace();
|
||||
// Only daily ingestion namespace has rows
|
||||
await writeMemoryCoreWorkspaceEntries({
|
||||
@@ -251,6 +290,6 @@ describe("dreaming artifact repair", () => {
|
||||
|
||||
const audit = await auditDreamingArtifacts({ workspaceDir });
|
||||
|
||||
expect(audit.sessionIngestionExists).toBe(true);
|
||||
expect(audit.sessionIngestionExists).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,6 @@ import path from "node:path";
|
||||
import { extractErrorCode } from "openclaw/plugin-sdk/error-runtime";
|
||||
import {
|
||||
clearMemoryCoreWorkspaceNamespace,
|
||||
DREAMING_DAILY_INGESTION_NAMESPACE,
|
||||
DREAMING_SESSION_INGESTION_FILES_NAMESPACE,
|
||||
DREAMING_SESSION_INGESTION_SEEN_NAMESPACE,
|
||||
readMemoryCoreWorkspaceEntries,
|
||||
@@ -213,10 +212,11 @@ export async function auditDreamingArtifacts(params: {
|
||||
// Fall back to SQLite plugin state when the legacy JSON file was archived by migration.
|
||||
if (!sessionIngestionExists) {
|
||||
try {
|
||||
// Daily ingestion tracks memory/*.md independently; session repair must not
|
||||
// report or clear that healthy bookkeeping when rebuilding the session corpus.
|
||||
const ingestionNamespaces = [
|
||||
DREAMING_SESSION_INGESTION_FILES_NAMESPACE,
|
||||
DREAMING_SESSION_INGESTION_SEEN_NAMESPACE,
|
||||
DREAMING_DAILY_INGESTION_NAMESPACE,
|
||||
] as const;
|
||||
for (const namespace of ingestionNamespaces) {
|
||||
const entries = await readMemoryCoreWorkspaceEntries({
|
||||
|
||||
Reference in New Issue
Block a user