Skip to content

Commit 4bd7205

Browse files
authored
fix(memory-lancedb): accept dreaming config for slot-owned memory (openclaw#63874)
Merged via squash. Prepared head SHA: 9aaf29b Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com> Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com> Reviewed-by: @mbelinky
1 parent 820dc38 commit 4bd7205

5 files changed

Lines changed: 120 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Docs: https://docs.openclaw.ai
4949
- Matrix/runtime: resolve the verification/bootstrap runtime from a distinct packaged Matrix entry so global npm installs stop failing on crypto bootstrap with missing-module or recursive runtime alias errors. (#59249) Thanks @gumadeiras.
5050
- Matrix/streaming: preserve ordered block flushes before tool, message, and agent boundaries, add explicit `channels.matrix.blockStreaming` opt-in so Matrix `streaming: "off"` stays final-only by default, and move MiniMax plain-text final handling into the MiniMax provider runtime instead of the shared core heuristic. (#59266) thanks @gumadeiras
5151
- Gateway/agents: fix stale run-context TTL cleanup so the new maintenance sweep compiles and resets orphaned run sequence state correctly. (#52731) thanks @artwalker
52+
- Memory/lancedb: accept `dreaming` config when `memory-lancedb` owns the memory slot so Dreaming surfaces can read slot-owner settings without schema rejection. (#63874) Thanks @mbelinky.
5253

5354
## 2026.4.9
5455

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import fs from "node:fs";
2+
import { describe, expect, it } from "vitest";
3+
import { validateJsonSchemaValue } from "../../src/plugins/schema-validator.js";
4+
import { memoryConfigSchema } from "./config.js";
5+
6+
const manifest = JSON.parse(
7+
fs.readFileSync(new URL("./openclaw.plugin.json", import.meta.url), "utf-8"),
8+
) as { configSchema: Record<string, unknown> };
9+
10+
describe("memory-lancedb config", () => {
11+
it("accepts dreaming in the manifest schema and preserves it in runtime parsing", () => {
12+
const manifestResult = validateJsonSchemaValue({
13+
schema: manifest.configSchema,
14+
cacheKey: "memory-lancedb.manifest.dreaming",
15+
value: {
16+
embedding: {
17+
apiKey: "sk-test",
18+
},
19+
dreaming: {
20+
enabled: true,
21+
},
22+
},
23+
});
24+
25+
const parsed = memoryConfigSchema.parse({
26+
embedding: {
27+
apiKey: "sk-test",
28+
},
29+
dreaming: {
30+
enabled: true,
31+
},
32+
});
33+
34+
expect(manifestResult.ok).toBe(true);
35+
expect(parsed.dreaming).toEqual({
36+
enabled: true,
37+
});
38+
});
39+
40+
it("still rejects unrelated unknown top-level config keys", () => {
41+
expect(() => {
42+
memoryConfigSchema.parse({
43+
embedding: {
44+
apiKey: "sk-test",
45+
},
46+
dreaming: {
47+
enabled: true,
48+
},
49+
unexpected: true,
50+
});
51+
}).toThrow("memory config has unknown keys: unexpected");
52+
});
53+
54+
it("rejects non-object dreaming values in runtime parsing", () => {
55+
expect(() => {
56+
memoryConfigSchema.parse({
57+
embedding: {
58+
apiKey: "sk-test",
59+
},
60+
dreaming: true,
61+
});
62+
}).toThrow("dreaming config must be an object");
63+
});
64+
});

extensions/memory-lancedb/config.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type MemoryConfig = {
1010
baseUrl?: string;
1111
dimensions?: number;
1212
};
13+
dreaming?: Record<string, unknown>;
1314
dbPath?: string;
1415
autoCapture?: boolean;
1516
autoRecall?: boolean;
@@ -97,7 +98,7 @@ export const memoryConfigSchema = {
9798
const cfg = value as Record<string, unknown>;
9899
assertAllowedKeys(
99100
cfg,
100-
["embedding", "dbPath", "autoCapture", "autoRecall", "captureMaxChars"],
101+
["embedding", "dreaming", "dbPath", "autoCapture", "autoRecall", "captureMaxChars"],
101102
"memory config",
102103
);
103104

@@ -118,6 +119,15 @@ export const memoryConfigSchema = {
118119
throw new Error("captureMaxChars must be between 100 and 10000");
119120
}
120121

122+
const dreaming =
123+
typeof cfg.dreaming === "undefined"
124+
? undefined
125+
: cfg.dreaming && typeof cfg.dreaming === "object" && !Array.isArray(cfg.dreaming)
126+
? (cfg.dreaming as Record<string, unknown>)
127+
: (() => {
128+
throw new Error("dreaming config must be an object");
129+
})();
130+
121131
return {
122132
embedding: {
123133
provider: "openai",
@@ -127,6 +137,7 @@ export const memoryConfigSchema = {
127137
typeof embedding.baseUrl === "string" ? resolveEnvVars(embedding.baseUrl) : undefined,
128138
dimensions: typeof embedding.dimensions === "number" ? embedding.dimensions : undefined,
129139
},
140+
dreaming,
130141
dbPath: typeof cfg.dbPath === "string" ? cfg.dbPath : DEFAULT_DB_PATH,
131142
autoCapture: cfg.autoCapture === true,
132143
autoRecall: cfg.autoRecall !== false,

extensions/memory-lancedb/openclaw.plugin.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
"label": "Auto-Recall",
3939
"help": "Automatically inject relevant memories into context"
4040
},
41+
"dreaming": {
42+
"label": "Dreaming",
43+
"help": "Optional dreaming config consumed when this plugin owns the memory slot"
44+
},
4145
"captureMaxChars": {
4246
"label": "Capture Max Chars",
4347
"help": "Maximum message length eligible for auto-capture",
@@ -77,6 +81,9 @@
7781
"autoRecall": {
7882
"type": "boolean"
7983
},
84+
"dreaming": {
85+
"type": "object"
86+
},
8087
"captureMaxChars": {
8188
"type": "number",
8289
"minimum": 100,

src/memory-host-sdk/dreaming.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@ describe("memory dreaming host helpers", () => {
156156
"America/Los_Angeles",
157157
),
158158
).toBe(true);
159+
});
160+
161+
it("resolves the configured memory-slot plugin id", () => {
159162
expect(
160163
resolveMemoryDreamingPluginId({
161164
plugins: {
@@ -165,6 +168,9 @@ describe("memory dreaming host helpers", () => {
165168
},
166169
} as OpenClawConfig),
167170
).toBe("memos-local-openclaw-plugin");
171+
});
172+
173+
it("reads dreaming config from the configured memory-slot owner", () => {
168174
expect(
169175
resolveMemoryDreamingPluginConfig({
170176
plugins: {
@@ -187,6 +193,36 @@ describe("memory dreaming host helpers", () => {
187193
enabled: true,
188194
},
189195
});
196+
});
197+
198+
it("reads dreaming config from memory-lancedb when it owns the memory slot", () => {
199+
expect(
200+
resolveMemoryDreamingPluginConfig({
201+
plugins: {
202+
slots: {
203+
memory: "memory-lancedb",
204+
},
205+
entries: {
206+
"memory-lancedb": {
207+
config: {
208+
dreaming: {
209+
enabled: true,
210+
frequency: "0 */6 * * *",
211+
},
212+
},
213+
},
214+
},
215+
},
216+
} as OpenClawConfig),
217+
).toEqual({
218+
dreaming: {
219+
enabled: true,
220+
frequency: "0 */6 * * *",
221+
},
222+
});
223+
});
224+
225+
it("falls back to memory-core when no memory slot override is configured", () => {
190226
expect(
191227
resolveMemoryDreamingPluginConfig({
192228
plugins: {

0 commit comments

Comments
 (0)