#dreaming + memory plugin
1 messages · Page 1 of 1 (latest)
Short version: there are no dedicated dreaming lifecycle hooks like onDreamStart / onDreamEnd today.
Dreaming is implemented by the active memory plugin using normal plugin APIs. If you want your memory plugin to support it, the pattern is basically:
1. Be the active memory plugin
Register the unified memory capability, not just tools/hooks:
api.registerMemoryCapability({
promptBuilder: buildPromptSection,
flushPlanResolver: buildFlushPlan,
runtime: memoryRuntime,
publicArtifacts: {
listArtifacts,
},
});
That is the preferred seam from docs/plugins/sdk-overview.md.
2. Add a dreaming config block to your plugin manifest
When your plugin owns plugins.slots.memory, OpenClaw resolves dreaming config from:
plugins.entries["your-plugin-id"].config.dreaming
That lookup comes from:
resolveMemoryDreamingPluginId(...)resolveMemoryDreamingPluginConfig(...)
So your openclaw.plugin.json needs at least:
{
"kind": "memory",
"configSchema": {
"type": "object",
"properties": {
"dreaming": {
"type": "object"
}
}
}
}
If you want parity with memory-core, mirror its dreaming schema shape.
3. Reconcile a cron at startup
memory-core uses:
api.registerHook("gateway:startup", async (event) => {
await reconcileManagedDreamingCron(...)
});
That hook creates/updates a cron job which wakes the main session with a hidden system token.
4. Run the dream sweep from before_agent_reply
This is the main runtime hook to know about:
api.on("before_agent_reply", async (event, ctx) => {
if (ctx.trigger !== "heartbeat") return;
if (!event.cleanedBody.includes(DREAM_TOKEN)) return;
const dreaming = resolveMemoryDreamingConfig({
pluginConfig: api.pluginConfig,
cfg: api.config,
});
if (!dreaming.enabled) {
return { handled: true, reason: "dreaming disabled" };
}
for (const { workspaceDir } of resolveMemoryDreamingWorkspaces(api.config)) {
await runDreamSweep({ workspaceDir, dreaming, api });
}
return { handled: true, reason: "dreaming processed" };
});
So the important hook is before_agent_reply, specifically when ctx.trigger === "heartbeat".
5. Write standard artifacts/events
If you want to integrate cleanly with the rest of the ecosystem, also write:
- dream reports under
memory/dreaming/<phase>/YYYY-MM-DD.md - optional inline daily-note blocks
- memory event log at
memory/.dreams/events.jsonl
Useful helpers:
appendMemoryHostEvent(...)
readMemoryHostEvents(...)resolveMemoryHostEventLogPath(...)formatMemoryDreamingDay(...)
Standard event types:
memory.recall.recordedmemory.promotion.appliedmemory.dream.completed
6. Optional: ship your own /dreaming command
memory-core registers registerDreamingCommand(api), but today that command still writes to plugins.entries.memory-core.config.dreaming.enabled.
So if your plugin is not memory-core, I would add your own /dreaming command that writes to your plugin’s config path.
The hooks/events to be aware of
Actual hooks
api.registerHook("gateway:startup", ...)for cron reconciliationapi.on("before_agent_reply", ...)for heartbeat-triggered dream execution
Not really “hooks”, but important integration points
plugins.slots.memoryplugins.entries.<your-plugin>.config.dreamingmemory.dream.completedmemory.recall.recordedmemory.promotion.applied
No special dreaming hook exists
There is not currently a dedicated:
dreaming:startdreaming:phase
dreaming:complete
API for plugins.
Best reference implementation
Copy the shape of memory-core:
extensions/memory-core/index.tsextensions/memory-core/src/dreaming.tsextensions/memory-core/src/dreaming-command.tsextensions/memory-core/src/dreaming-markdown.ts
And for config resolution / shared helpers:
src/memory-host-sdk/dreaming.ts