Skip to content

Commit 7f9f180

Browse files
committed
test: add outcome normalization tests for dreaming events
Tests for: - Successful dream events omit outcome (backward compatible) - Failed dream events record outcome and error fields - Partial outcome on deep dreaming events
1 parent 367fbea commit 7f9f180

1 file changed

Lines changed: 69 additions & 1 deletion

File tree

extensions/memory-core/src/memory-events.test.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
readMemoryHostEvents,
77
} from "openclaw/plugin-sdk/memory-host-events";
88
import { describe, expect, it } from "vitest";
9-
import { writeDailyDreamingPhaseBlock } from "./dreaming-markdown.js";
9+
import { writeDailyDreamingPhaseBlock, writeDeepDreamingReport } from "./dreaming-markdown.js";
1010
import {
1111
applyShortTermPromotions,
1212
rankShortTermPromotionCandidates,
@@ -188,4 +188,72 @@ describe("memory host event journal integration", () => {
188188
expect(dreamEvent.lineCount).toBe(2);
189189
expect(dreamEvent.storageMode).toBe("both");
190190
});
191+
192+
it("omits outcome on successful dreaming events when no outcome is provided", async () => {
193+
const workspaceDir = await createTempWorkspace("memory-core-dream-outcome-implicit-");
194+
195+
await writeDailyDreamingPhaseBlock({
196+
workspaceDir,
197+
phase: "rem",
198+
bodyLines: ["- REM insight"],
199+
nowMs: Date.UTC(2026, 3, 5, 14, 0, 0),
200+
storage: { mode: "inline", separateReports: false },
201+
});
202+
203+
const events = await readMemoryHostEvents({ workspaceDir });
204+
expect(events).toHaveLength(1);
205+
const dreamEvent = events[0];
206+
if (dreamEvent?.type !== "memory.dream.completed") {
207+
throw new Error("expected dream completion event");
208+
}
209+
// Backward-compatible: successful events without explicit outcome omit the field.
210+
expect(dreamEvent.outcome).toBeUndefined();
211+
expect(dreamEvent.error).toBeUndefined();
212+
});
213+
214+
it("records outcome and error on failed dreaming events", async () => {
215+
const workspaceDir = await createTempWorkspace("memory-core-dream-outcome-failed-");
216+
217+
await writeDailyDreamingPhaseBlock({
218+
workspaceDir,
219+
phase: "light",
220+
bodyLines: [],
221+
nowMs: Date.UTC(2026, 3, 5, 13, 0, 0),
222+
storage: { mode: "inline", separateReports: false },
223+
outcome: "failed",
224+
error: "promoted file write rejected: EACCES",
225+
});
226+
227+
const events = await readMemoryHostEvents({ workspaceDir });
228+
expect(events).toHaveLength(1);
229+
const dreamEvent = events[0];
230+
if (dreamEvent?.type !== "memory.dream.completed") {
231+
throw new Error("expected dream completion event");
232+
}
233+
expect(dreamEvent.outcome).toBe("failed");
234+
expect(dreamEvent.error).toBe("promoted file write rejected: EACCES");
235+
expect(dreamEvent.phase).toBe("light");
236+
});
237+
238+
it("records partial outcome on dreaming events", async () => {
239+
const workspaceDir = await createTempWorkspace("memory-core-dream-outcome-partial-");
240+
241+
await writeDeepDreamingReport({
242+
workspaceDir,
243+
bodyLines: ["- Partial result"],
244+
nowMs: Date.UTC(2026, 3, 5, 13, 0, 0),
245+
storage: { mode: "inline", separateReports: false },
246+
outcome: "partial",
247+
});
248+
249+
const events = await readMemoryHostEvents({ workspaceDir });
250+
expect(events).toHaveLength(1);
251+
const dreamEvent = events[0];
252+
if (dreamEvent?.type !== "memory.dream.completed") {
253+
throw new Error("expected dream completion event");
254+
}
255+
expect(dreamEvent.outcome).toBe("partial");
256+
expect(dreamEvent.error).toBeUndefined();
257+
expect(dreamEvent.phase).toBe("deep");
258+
});
191259
});

0 commit comments

Comments
 (0)